%% COPYRIGHT 2008 by Manuel Luque, Arnaud Schmittbuhl, Jean-Paul Vignault
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt.
\csname PSTSOLIDESIIIDLoaded\endcsname
\let\PSTSOLIDESIIIDLoaded\endinput
% Requires PSTricks, pst-xkey and pst-node packages
\ifx\PSTricksLoaded\endinput\else\input pstricks.tex\fi
\ifx\PSTXKeyLoaded\endinput\else\input pst-xkey \fi
\ifx\PSTnodesLoaded\endinput\else\input pst-node \fi
\ifx\MultidoLoaded\endinput\else\input multido.tex \fi
% JPV & ML & AS
\def\fileversion{3.02}
\def\filedate{2008/01/15}
\message{`PSTSOLIDESIIID' v\fileversion, \filedate}
%
\pstheader{solides.pro}

\edef\PstAtCode{\the\catcode`\@} \catcode`\@=11\relax
\pst@addfams{pst-solides3d}
\SpecialCoor
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Definition des differentes variables pour PSTricks
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% point de vue et rotations de l'objet
% distance de l'ecran a l'observateur
\define@key[psset]{pst-solides3d}{Decran}{\def\pst@solides@Decran{#1}}% distance de l'ecran
%
\define@key[psset]{pst-solides3d}{viewpoint}{\def\pst@solides@viewpoint{#1}}% position de l'observateur
\psset[pst-solides3d]{viewpoint=10 10 10}% coordonnees cartesiennes
% rotation autour de Ox en degres
\define@key[psset]{pst-solides3d}{RotX}{\def\psk@solides@RotX{#1}}
% rotation autour de Oy en degres
\define@key[psset]{pst-solides3d}{RotY}{\def\psk@solides@RotY{#1}}
% rotation autour de Oz en degres
\define@key[psset]{pst-solides3d}{RotZ}{\def\psk@solides@RotZ{#1}}

\psset[pst-solides3d]{RotZ=0,RotX=0,RotY=0,Decran=50}%

% parametres propres a chaque objet
\define@key[psset]{pst-solides3d}{resolution}{\def\pst@solides@resolution{#1}} % nb points par courbe
\define@key[psset]{pst-solides3d}{no}{\def\pst@solides@no{#1}} % numero face du solide
\define@key[psset]{pst-solides3d}{phi}{\def\pst@solides@phi{#1}} % angle calotte sphere
\define@key[psset]{pst-solides3d}{theta}{\def\pst@solides@theta{#1}} % angle calotte sphere
\define@key[psset]{pst-solides3d}{r0}{\def\pst@solides@rO{#1}} % rayon interieur tore
\define@key[psset]{pst-solides3d}{r1}{\def\pst@solides@rI{#1}} % rayon moyen tore
\define@key[psset]{pst-solides3d}{R}{\def\pst@solides@R{#1}} % rayon moyen tore
\define@key[psset]{pst-solides3d}{r}{\def\pst@solides@r{#1}} % rayon de la sphere circonscrite
\define@key[psset]{pst-solides3d}{a}{\def\pst@solides@a{#1}} % arete du cube (1 du parallelepipede)
\define@key[psset]{pst-solides3d}{b}{\def\pst@solides@b{#1}} % arete 2 du parallelepipede
\define@key[psset]{pst-solides3d}{c}{\def\pst@solides@c{#1}} % arete 3 du parallelepipede
\define@key[psset]{pst-solides3d}{h}{\def\pst@solides@h{#1}} % hauteur du cylindre, du cone, du prisme
\define@key[psset]{pst-solides3d}{base}{\def\pst@solides@base{#1}} % base du prisme
\psset[pst-solides3d]{base=-1 -1 1 -1 0 1}% coordonnees d'un triangle, base triangulaire par defaut
\define@key[psset]{pst-solides3d}{axe}{\def\pst@solides@axe{#1}} % axe du prisme
\psset[pst-solides3d]{axe=0 0 1}% vecteur definissant la direction de l'axe du prisme
\psset[pst-solides3d]{R=4,r1=4,r0=1.5,r=2,no=0,a=4,b=a,c=a,h=6,phi=0,theta=90,resolution=36}
\define@key[psset]{pst-solides3d}{hauteurlignedeniveau}{\def\psk@solides@hauteurlignedeniveau{#1}}
\psset[pst-solides3d]{hauteurlignedeniveau=0}%
\define@key[psset]{pst-solides3d}{linewidthlignedeniveau}{\def\psk@solides@linewidthlignedeniveau{#1}}
\psset[pst-solides3d]{linewidthlignedeniveau=1}%
\define@key[psset]{pst-solides3d}{definition}{\def\pst@solides@definition{#1}} %
\psset[pst-solides3d]{definition=}%
\define@key[psset]{pst-solides3d}{args}{\def\pst@solides@args{#1}} %
\psset[pst-solides3d]{args=}%
\define@key[psset]{pst-solides3d}{transform}{\def\pst@solides@transform{#1}} %
\psset[pst-solides3d]{transform=}%

\def\Section{%
         R h 2 div neg % sommet 1
         R h 2 div % sommet 2
         r h 2 div % sommet 3
         r h 2 div neg % sommet 4
            }
\define@key[psset]{pst-solides3d}{section}{\def\pst@solides@section{#1}} % section de l'objet de revolution
\psset[pst-solides3d]{section=\Section}% coordonnees des sommets de la section

%% decalage pourle prisme
\define@key[psset]{pst-solides3d}{decal}{\def\pst@solides@decal{#1}}
\psset[pst-solides3d]{decal=-2}% decalage par defaut

% teinte des faces exterieures de l'objet a partir de PSTricks
% donnee par filcollor
% teinte des faces interieures de l'objet a partir de PSTricks
\define@key[psset]{pst-solides3d}{incolor}{%
\pst@getcolor{#1}\psincolor}
\psset[pst-solides3d]{incolor=green}
%
\define@key[psset]{pst-solides3d}{couleurlignedeniveau}{%
\pst@getcolor{#1}\pscouleurlignedeniveau}
\psset[pst-solides3d]{couleurlignedeniveau=green}
%% couleurs definies par l'utilisateur
\define@key[psset]{pst-solides3d}{color1}{%
\pst@getcolor{#1}\pscolora}
\psset[pst-solides3d]{color1=cyan}
%
\define@key[psset]{pst-solides3d}{color2}{%
\pst@getcolor{#1}\pscolorb}
\psset[pst-solides3d]{color2=magenta}
%
\define@key[psset]{pst-solides3d}{color3}{%
\pst@getcolor{#1}\pscolorc}
\psset[pst-solides3d]{color3=blue}
%
\define@key[psset]{pst-solides3d}{color4}{%
\pst@getcolor{#1}\pscolord}
\psset[pst-solides3d]{color4=red}
%
% resolution du trace
\newcount\test@mode
\define@key[psset]{pst-solides3d}{mode}{% resolution : mode=0,1,2, 3,4 ou 5
  \test@mode=#1\relax%
  \ifnum\test@mode>4%
    \typeout{mode must be 0,1,2,3 or 4 and not `\the\test@mode'. Value 4 forced.}\test@mode=4%
  \fi%
\edef\pst@solides@mode{\the\test@mode}}%
\psset[pst-solides3d]{mode=2}%

\define@boolkey[psset]{pst-solides3d}[Pst@]{SphericalCoor}[true]{}
\psset{SphericalCoor=false}

\define@boolkey[psset]{pst-solides3d}[Pst@]{grid}[false]{}
\psset{grid=true}

\define@boolkey[psset]{pst-solides3d}[Pst@]{tracelignedeniveau}[true]{}
\psset{tracelignedeniveau=false}

\define@boolkey[psset]{pst-solides3d}[Pst@]{hollow}[true]{}
\psset{hollow=false}

\define@boolkey[psset]{pst-solides3d}[Pst@]{biface}[true]{}
\psset{biface=true}%

\define@boolkey[psset]{pst-solides3d}[Pst@]{axesboxed}[true]{}
\psset{axesboxed=false}%

%% faces a enlever
\define@key[psset]{pst-solides3d}{rm}{\def\pst@solides@CoordinatesRm{#1}}
\psset[pst-solides3d]{rm=}% pas de faces par defaut
%% nom de la variable de sauvegarde du solide considere
\define@key[psset]{pst-solides3d}{name}{\def\pst@solides@name{#1}}
\psset[pst-solides3d]{name=}% pas de nom par defaut
%% nom de la variable de sauvegarde du solide sur lequel on doit projeter
\define@key[psset]{pst-solides3d}{solidname}{\def\pst@solides@solidname{#1}}
\psset[pst-solides3d]{solidname=}% pas de nom par defaut
%% nom du fichier externe
\define@key[psset]{pst-solides3d}{file}{\def\pst@solides@file{#1}}
\psset[pst-solides3d]{file=}% pas de fichier par defaut
%% couleurs de faces isolees
\define@key[psset]{pst-solides3d}{fcol}{\def\pst@solides@fcol{#1}}
\psset[pst-solides3d]{fcol=}% pas de faces par defaut
%% les degrades ``hue''
\define@key[psset]{pst-solides3d}{hue}{\def\pst@solides@hue{#1}}
\psset[pst-solides3d]{hue=}% pas de degrade externe par defaut
\define@key[psset]{pst-solides3d}{inhue}{\def\pst@solides@inhue{#1}}
\psset[pst-solides3d]{inhue=}% pas de degrade interne par defaut
\define@key[psset]{pst-solides3d}{inouthue}{\def\pst@solides@inouthue{#1}}
\psset[pst-solides3d]{inouthue=}% pas de degrade total par defaut
%% definition des faces et des sommets d'un nouveau solide
\define@key[psset]{pst-solides3d}{sommets}{\def\pst@solides@sommets{#1}}
\psset[pst-solides3d]{sommets=}% pas de sommet par defaut
%% \define@key[psset]{pst-solides3d}{faces}{\def\pst@solides@faces{#1}}
%% \psset[pst-solides3d]{faces=}% pas de face par defaut
\define@key[psset]{pst-solides3d}{faces}{\def\pst@solides@faces{#1}}
\psset[pst-solides3d]{faces={}}% valeurs par defaut
%% numerotation des faces
\define@key[psset]{pst-solides3d}{numfaces}{\def\pst@solides@numfaces{#1}}
\psset[pst-solides3d]{numfaces=}% pas de numerotation defaut
%% numerotation des sommets
\define@key[psset]{pst-solides3d}{num}{\def\pst@solides@num{#1}}
\psset[pst-solides3d]{num=}% pas de numerotation defaut
%% pointage des sommets
\define@key[psset]{pst-solides3d}{show}{\def\pst@solides@show{#1}}
\psset[pst-solides3d]{show=}% pas de pointage par defaut
%% maillage de l'utilisateur
\define@key[psset]{pst-solides3d}{ngrid}{\def\pst@solides@ngrid{#1}}
\psset[pst-solides3d]{ngrid=}% pas de faces par defaut

% source de la lumiere :
\define@key[psset]{pst-solides3d}{lightsrc}{\def\pst@solides@CoordinatesLight{#1}}
\psset[pst-solides3d]{lightsrc=}% pas de coordonnees par defaut
% intensite de la lumiere
\define@key[psset]{pst-solides3d}{lightintensity}{\def\pst@solides@lightintensity{#1}}
\psset[pst-solides3d]{lightintensity=2}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Reservation des noms de macros
% #1=type de reservation (action, object...) associee a une liste qui
% doit forcement etre du type pst@solides@list@#1
\def\pst@solides@reservednames#1{%
\edef\@tempa{\csname pst@solides@list@#1\endcsname}
\@for \name:=\@tempa\do{%
  \expandafter\def\csname pst@solides@#1@\name\endcsname{}%
}}
% type de dessin
\def\pst@solides@list@action{none,draw,draw*,draw**}
%% Reservation de macros correspondants aux actions
\pst@solides@reservednames{action}
\define@key[psset]{pst-solides3d}{action}{%
  \ifcsname pst@solides@action@#1\endcsname
    \def\pst@solides@action{#1}%
  \else
    \@pstrickserr{This action is not authorized, the procedure draw** is
    chosen by default}{}%
  \fi}
% type par defaut = faces vues remplies
\psset[pst-solides3d]{action=draw**}%
%

% nature de l'objet
\def\pst@solides@list@object{%
tore,cube,tetrahedron,octahedron,icosahedron,dodecahedron,sphere,%
cylindre,cylindrecreux,cone,conecreux,tronccone,troncconecreux,%
grille,prisme,anneau,parallelepiped,prismecreux,ruban,calottesphere,face,%
surface,calottespherecreuse,polygoneregulier,fusion,new,chemin,courbeR2,courbe,%
surfaceparametree,texte,trigospherique,vecteur,ligne,objfile}
%% Reservation de macros correspondants aux objects
\pst@solides@reservednames{object}
\define@key[psset]{pst-solides3d}{object}{%
 \ifcsname pst@solides@object@#1\endcsname
   \def\psk@solides@object{pst-#1}%
 \else
    \@pstrickserr{The solid #1 is not defined, the solid by default is
    drawn}{}%
 \fi}
% solide par defaut
\psset[pst-solides3d]{object=tore}%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% pour le quadrillage 3d
\define@key[psset]{pst-solides3d}{spotX}{\def\pst@solides@@spotX{#1}}%
\define@key[psset]{pst-solides3d}{spotY}{\def\pst@solides@@spotY{#1}}%
\define@key[psset]{pst-solides3d}{spotZ}{\def\pst@solides@@spotZ{#1}}%
\define@key[psset]{pst-solides3d}{QZ}{\def\pst@solides@@QZ{#1}}%
\define@key[psset]{pst-solides3d}{Zmin}{\def\pst@solides@@Zmin{#1}}%
\define@key[psset]{pst-solides3d}{Zmax}{\def\pst@solides@@Zmax{#1}}%
\psset[pst-solides3d]{spotX=dr,spotY=dl,spotZ=l,QZ=0,Zmin=-4,Zmax=4}
% spotX, Y, Z vaut de 0 a 360 degres pour placer les valeurs correctement
% QZ translation du quadrillage suivant l'axe Oz


\def\gridIIID{\pst@object{gridIIID}}
%% usage : \gridIIID[options](x_min,x_max)(y_min,y_max)(z_min,z_max)
\def\gridIIID@i(#1,#2)(#3,#4){%
  \pst@killglue%
  \begingroup%
  \use@par%
\psSolid[object=parallelepiped,
   tracelignedeniveau=false,
   a={#2 #1 sub},b={#4 #3 sub},c={\pst@solides@@Zmax\space \pst@solides@@Zmin\space sub},action=draw](0,0,\pst@solides@@QZ)
\pst@cnta=#2 %
\advance\pst@cnta by -#1 \advance\pst@cnta by 1
\multido{\ix=#1+1}{\pst@cnta}{%
    \psPoint(\ix\space,#4,\pst@solides@@Zmin){X1}
    \psPoint(\ix\space,#4 .2 add,\pst@solides@@Zmin){X2}
    \psline(X1)(X2)
    \uput[\pst@solides@@spotX](X1){\small\ix}}
\pst@cnta=#4 %
\advance\pst@cnta by -#3 \advance\pst@cnta by 1%
\multido{\iy=#3+1}{\pst@cnta}{%
    \psPoint(#2,\iy\space,\pst@solides@@Zmin){Y1}
    \psPoint(#2 .2 add,\iy\space,\pst@solides@@Zmin){Y2}
    \psline(Y1)(Y2)
    \uput[\pst@solides@@spotY](Y1){\small\iy}}
\pst@cnta=\pst@solides@@Zmax %
\advance\pst@cnta by -\pst@solides@@Zmin \advance\pst@cnta by 1
\multido{\iz=\pst@solides@@Zmin+1}{\pst@cnta}{%
    \psPoint(#2,#3,\iz\space){Z1}
    \psPoint(#2,#3 .2 sub,\iz\space){Z2}
    \psline(Z1)(Z2)
    \uput[\pst@solides@@spotZ](Z1){\small\iz}}
\psPoint(0,0,\pst@solides@@Zmax\space 3 add){Z'}
\psPoint(#2 2 add,0,0){X'}
\psPoint(0,#4 2 add, 0){Y'}
\psPoint(0,0,\pst@solides@@Zmax){Z}
\psPoint(#2,0,0){X}
\psPoint(0,#4,0){Y}
\psPoint(0,0,0){O}
\uput[\pst@solides@@spotY](X'){$x$}
\uput[\pst@solides@@spotX](Y'){$y$}
\uput[u](Z'){$z$}
\psline[linestyle=dashed](O)(X)
\psline[linestyle=dashed](O)(Y)
\psline[linestyle=dashed](O)(Z)
%\psset{linewidth=2\pslinewidth}
\psline{->}(Z)(Z')\psline{->}(Y)(Y')\psline{->}(X)(X')
  \endgroup%
  \ignorespaces%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% code insere dans le .ps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
\pst@def{optionssolides}<%
/xunit {\pst@number\psunit } def
%% /cm {\pst@number\psunit mul} def
%% /cm_1 {\pst@number\psunit div} def
/decal \pst@solides@decal\space def % decalage
/viewpointXYZ {\pst@solides@viewpoint} def
/Decran \pst@solides@Decran\space def % distance de l'ecran
%
/RotX \psk@solides@RotX\space def
/RotY \psk@solides@RotY\space def
/RotZ \psk@solides@RotZ\space def
%
/hauteurlignedeniveau \psk@solides@hauteurlignedeniveau\space def
/linewidthlignedeniveau \psk@solides@linewidthlignedeniveau\space def
/fontsize {\pst@solides@fontsize\space \pst@number\psunit mul 28.45 div } bind def
%
\ifPst@visibility
   /projectionsifacevisible true def
\else
   /projectionsifacevisible false def
\fi
%
/R \pst@solides@R\space def % pour le tore
/r1 \pst@solides@rI\space def % pour le tore
/r0 \pst@solides@rO\space def % pour le tore
/resolution \pst@solides@resolution\space def % pour le nb de points par courbe
/phi \pst@solides@phi\space def % pour la calotte spherique
/theta \pst@solides@theta\space def % pour la calotte spherique
/r \pst@solides@r\space def % rayon sphere circonscrite
/a \pst@solides@a\space def % arete du cube (1 du parallelepipede)
/b \pst@solides@b\space def % arete 2 du parallelepipede
/c \pst@solides@c\space def % arete 3 du parallelepipede
/h \pst@solides@h\space def % hauteur du cylindre, du cone, du prisme
/section {\pst@solides@section} def % section de l'objet de revolution
/base [ \pst@solides@base ] def
/axe  { \pst@solides@axe } def
/function  { \pst@solides@function } def
/definition  { \pst@solides@definition } def
/args  { \pst@solides@args} def
/Mode \pst@solides@mode\space def % resolution du trace
/lightintensity \pst@solides@lightintensity\space def % intensite de la lumiere
%
/solidlinewidth {\pst@number\pslinewidth} def
/linecolor  {\pst@usecolor\pslinecolor} def
/linestyle  {\pslinestyle} def
/fillcolor  {\pst@usecolor\psfillcolor currentrgbcolor} def
/fillincolor  {\pst@usecolor\psincolor currentrgbcolor} def
/couleurlignedeniveau  {\pst@usecolor\pscouleurlignedeniveau currentrgbcolor} def
%
/color1 {\pst@usecolor\pscolora currentrgbcolor} def
/color2 {\pst@usecolor\pscolorb currentrgbcolor} def
/color3 {\pst@usecolor\pscolorc currentrgbcolor} def
/color4 {\pst@usecolor\pscolord currentrgbcolor} def
%
/range [ \pst@solides@range ] def
/action {\pst@solides@action} def
%
\ifx\pst@solides@CoordinatesLight\@empty
    \else
/lightsrc {\pst@solides@CoordinatesLight} def
\fi
%
\ifx\pst@solides@CoordinatesRm\@empty
/rmfaces [] def
    \else
/rmfaces [\pst@solides@CoordinatesRm] def
\fi
%
\ifx\pst@solides@transform\@empty
    \else
/pst-transformoption { \pst@solides@transform} def
\fi
%
\ifx\pst@solides@name\@empty
    \else
/solidname /\pst@solides@name\space def
\fi
%
\ifx\pst@solides@fcol\@empty
/fcol [] def
    \else
/fcol [\pst@solides@fcol] def
\fi
%
\ifx\pst@solides@hue\@empty
/solidhue [] def
    \else
/solidhue [\pst@solides@hue] def
\fi
\ifx\pst@solides@inouthue\@empty
/solidinouthue [] def
    \else
/solidinouthue [\pst@solides@inouthue] def
\fi
\ifx\pst@solides@inhue\@empty
/solidinhue [] def
    \else
/solidinhue [\pst@solides@inhue] def
\fi
%
%% \ifPst@hue
%%    /solidhue true def
%% \else
%%    /solidhue false def
%% \fi
%
\ifx\pst@solides@sommets\@empty
/sommets [] def
    \else
/sommets [\pst@solides@sommets] def
\fi
%
\ifx\pst@solides@faces\@empty
/faces [] def
    \else
/faces [\pst@solides@faces] def
\fi
%
\ifx\pst@solides@show\@empty
/solidshow [] def
    \else
/solidshow [\pst@solides@show] def
\fi
%
\ifx\pst@solides@num\@empty
/solidnum [] def
    \else
/solidnum [\pst@solides@num] def
\fi
%
\ifx\pst@solides@numfaces\@empty
/solidnumf [] def
    \else
/solidnumf [\pst@solides@numfaces] def
\fi
%
\ifx\pst@solides@ngrid\@empty
/ngrid [] def
    \else
/ngrid [\pst@solides@ngrid] def
\fi
%
\ifPst@tracelignedeniveau
   /tracelignedeniveau? true def
\else
   /tracelignedeniveau? false def
\fi
%
\ifPst@grid
   /solidgrid true def
\else
   /solidgrid false def
\fi
\ifPst@hollow
   /solidhollow true def
\else
   /solidhollow false def
\fi
\ifPst@biface
   /solidbiface true def
\else
   /solidbiface false def
\fi
%% \ifPst@num
%%    /solidnum true def
%% \else
%%    /solidnum false def
%% \fi
%
/viewpointXYZ {\pst@solides@viewpoint} def
\ifPst@SphericalCoor
    viewpointXYZ /PHI ED /THETA ED /Dobs ED
%    CoefficientsMT
%% pour la 3D conventionnelle
%% Dony : graphisme scientifique : page 187
%% Editeur : Masson
/XpointVue {Dobs Cos1Cos2 mul} bind def
/YpointVue {Dobs Sin1Cos2 mul} bind def
/ZpointVue {Dobs Sin2 mul} bind def
    \else
    viewpointXYZ /ZpointVue ED /YpointVue ED /XpointVue ED
    /THETA {YpointVue XpointVue atan} bind def
    /PHI   {ZpointVue XpointVue dup mul YpointVue dup mul add sqrt atan} bind def
    /Dobs  {XpointVue dup mul YpointVue dup mul add ZpointVue dup mul add sqrt} bind def
%    CoefficientsMT
\fi
>%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro \psSolid
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\newif\ifsolidmemory
%\solidmemoryfalse

\define@boolkey[psset]{pst-solides3d}[Pst@]{solidmemory}[true]{}
\psset{solidmemory=false}%

\def\psSolid{\def\pst@par{}\pst@object{psSolid}}
\def\psSolid@i{\@ifnextchar({\psSolid@ii}{\psSolid@ii(0,0,0)}}
\def\psSolid@ii(#1,#2,#3){{%
    \use@par
\ifPst@solidmemory
  \else
\begin@ClosedObj
\fi
    \addto@pscode{%
    1 setlinejoin
    \tx@optionssolides
    SolidesDict begin
    /CX #1 def
    /CY #2 def
    /CZ #3 def
    % nature du solide
    \psk@solides@object\space
%
 end
}% fin du code ps
\ifPst@solidmemory
  \else
\end@ClosedObj%
\fi
\ignorespaces
}}

\def\composeSolid{\use@pscode}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro \codejps
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\codejps#1{{%
\define@key[psset]{pst-solides3d}{object}{\def\psk@solides@object{#1}}
\psSolid[object=#1](0,0,0)}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro \psTransformPoint
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% transformation d'un point
% \pstransformIIID[RotX=,...](x y z)(CX,CY,CZ)
% Rotation d'un point(x y z)
% autour des axes Ox, Oy et Oz
% suivie
% de la translation au point (CX,CY,CZ)
\def\psTransformPoint{\def\pst@par{}\pst@object{psTransformPoint}}
\def\psTransformPoint@i(#1)(#2,#3,#4)#5{{% coordonnees cartesiennes
  \begin@SpecialObj
\pnode(!
    \tx@optionssolides
    SolidesDict begin
    #1 RotX RotY RotZ rotateOpoint3d
    #2 #3 #4 translatepoint3d
   3dto2d cm_1 exch cm_1 exch
   end){#5}%
   \end@SpecialObj
  }\ignorespaces}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro \psPoint
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% placer un point en particulier
% \psPoint[options du point de vue](x y z)
\def\psPoint{\def\pst@par{}\pst@object{psPoint}}
\def\psPoint@i(#1,#2,#3)#4{{% coordonnees cartesiennes
    \begin@SpecialObj
\pnode(!
    \tx@optionssolides
    SolidesDict begin
    #1 #2 #3
   3dto2d cm_1 exch cm_1 exch
   end){#4}%
   \end@SpecialObj
  }\ignorespaces%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% les axes IIId
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\axesIIID(#1,#2,#3)(#4,#5,#6){% axes 3d
  \psPoint(0,0,0){O}
    \psPoint(#1,0,0){X}
    \psPoint(0,#2,0){Y}
    \psPoint(0,0,#3){Z}
    \psPoint(#4,0,0){X'}
    \psPoint(0,#5,0){Y'}
    \psPoint(0,0,#6){Z'}
    \psline[linestyle=dashed](O)(X)
    \psline[linestyle=dashed](O)(Y)
    \psline[linestyle=dashed](O)(Z)
    \psline{->}(X)(X')
    \psline{->}(Y)(Y')
    \psline{->}(Z)(Z')
%    \psdots(X)(Y)(Z)
%    \uput[l](O){$O$}
    \uput[dl](X'){$x$}\uput[r](Y'){$y$}
    \uput[u](Z'){$z$}}


% pour assurer la compatibilite avec PSTricks-add
\define@boolkey[psset]{pst-solides3d}[Pst@]{algebraic}[true]{}
\psset[pst-solides3d]{algebraic=false}%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro \psSurface
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\psSurface{\pst@object{psSurface}}
\def\psSurface@i(#1,#2)(#3,#4)#5{{%
    \use@par
%% \def\hue{0 1 #3 #1 sub \pst@solides@dx\space div
%%              #4 #2 sub \pst@solides@dy\space div mul
%%  {/iF ED iF [1 iF #3 #1 sub \pst@solides@dx\space div
%%                   #4 #2 sub \pst@solides@dy\space div
%%                    mul div sub 0.75 1] (sethsbcolor) astr2str} for}
  \begin@ClosedObj
    \addto@pscode{%
    1 setlinejoin
    \tx@optionssolides
    SolidesDict begin
/CX 0 def /CY 0 def /CZ 0 def
/base [ #1 #3 #2 #4 ] def
 \ifPst@algebraic
/fonction
  (#5) tx@AlgToPs begin AlgToPs end cvx def
 \else
/fonction  { #5 } def
 \fi
/f {2 dict begin
   /y exch def
   /x exch def
 fonction
end } def
 pst-surface
 end
}% fin du code ps
 \ifPst@axesboxed
    \gridIIID(#1,#3)(#2,#4)
 \fi
    \end@ClosedObj%
}}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro \defFunction
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\def\defFunction{\@ifnextchar[{\defFunction@i}{\defFunction@i[]}}
\def\defFunction@i[#1]#2(#3)#4#5#6{\bgroup
  \pst@killglue
   \psset{#1}
    \defFunction@ii{#3}\edef\@tempa{\the\toks@}%
    \ifPst@algebraic\toks@={}%
     \def\@tempb{#4}\ifx\@tempb\@empty \else\store@toks@after\@tempb\fi
      \def\@tempb{#5}\ifx\@tempb\@empty \else\store@toks@after\@tempb\fi
       \def\@tempb{#6}\ifx\@tempb\@empty
                      \else\store@toks@after\@tempb\fi
         \pstVerb{/#2 { \@tempa \the\toks@ } def }%
    \else
     \pstVerb{/#2 { \the\toks@ #4 #5 #6} def }%
    \fi
\egroup}
\def\defFunction@ii#1{\defFunction@iii#1,,,\end}
\def\defFunction@iii#1,#2,#3,#4\end{%
  \toks@={}%
   \def\arg@ii{#1}\ifx\arg@ii\@empty \else\store@toks@before\arg@ii\fi
    \def\arg@ii{#2}\ifx\arg@ii\@empty \else\store@toks@before\arg@ii\fi
     \def\arg@ii{#3}\ifx\arg@ii\@empty
\else\store@toks@before\arg@ii\fi}
\def\store@toks@before#1{%
 \edef\@tmpPSDefns{/#1 exch def \the\toks@}%
  \global\toks@=\expandafter{\@tmpPSDefns}%
}
\def\store@toks@after#1{%
 \edef\@tmpPSDefns{\the\toks@ (#1) tx@AlgToPs begin AlgToPs end cvx }%
  \global\toks@=\expandafter{\@tmpPSDefns}%
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% la macro de projection
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% creation des variables pour PSTricks
\define@boolkey[psset]{pst-solides3d}[Pst@]{visibility}[false]{}
\psset{visibility=true}
\define@key[psset]{pst-solides3d}{normal}{\def\pst@solides@normal{#1}}
\psset[pst-solides3d]{normal=0 0 1}
% choix de la police et de la taille des caracteres en cm !!
\define@key[psset]{pst-solides3d}{PSfont}{\def\pst@solides@PSfont{/#1 }}
\define@key[psset]{pst-solides3d}{fontsize}{\def\pst@solides@fontsize{#1 }}
\psset[pst-solides3d]{PSfont=Times-Roman,fontsize=10}
% origine du plan
\define@key[psset]{pst-solides3d}{origine}{\def\pst@solides@origin{#1}} % origine du plan
\psset[pst-solides3d]{origine=0 0 0 }%
%% le range pour les fonctions numeriques
\define@key[psset]{pst-solides3d}{range}{\def\pst@solides@range{#1}}
\psset[pst-solides3d]{range=-5 5}% le range par defaut
%% le chemin a projeter
\define@key[psset]{pst-solides3d}{path}{\def\pst@solides@path{#1}}%
\psset[pst-solides3d]{path=newpath 0 0 moveto}% valeur par defaut
%% fonctions utilisees
\define@key[psset]{pst-solides3d}{function}{\def\pst@solides@function{#1}}%
\psset[pst-solides3d]{function=f}% valeur par defaut
% rotation du texte dans son plan
\define@key[psset]{pst-solides3d}{RotationAngleText}{\def\pst@solides@RotationAngleText{#1}} % origine du plan
\psset[pst-solides3d]{RotationAngleText=0 }%
% texte a projeter
\define@key[psset]{pst-solides3d}{text}{\def\pst@solides@text{#1}}
\psset[pst-solides3d]{text=}% pas de texte par defaut
% position du texte a projeter
\define@key[psset]{pst-solides3d}{pos}{\def\pst@solides@pos{#1}}
\psset[pst-solides3d]{pos=cc}% centre par defaut

%% transcription et inclusion des variables dans le fichier postscript
\pst@def{psProjection}<%
\ifPst@visibility
   /projectionsifacevisible true def
\else
   /projectionsifacevisible false def
\fi
/solidlinewidth {\pst@number\pslinewidth} def
/PSfont {\pst@solides@PSfont} def
/normale {\pst@solides@normal} bind def
/fontsize {\pst@solides@fontsize\space \pst@number\psunit mul 28.45 div } bind def
/origin {\pst@solides@origin} def
/RotationAngleText {\pst@solides@RotationAngleText} def
/range [ \pst@solides@range ] def
/path  { \pst@solides@path } def
/function  { \pst@solides@function } def
/texte (\pst@solides@text) def
/pos (\pst@solides@pos) def
\ifx\pst@solides@solidname\@empty
    \else
/solidprojname {\pst@solides@solidname\space} def
\fi
/noface \pst@solides@no\space def % no de la face du solide
/resolution \pst@solides@resolution\space def % pour le nb de points par courbe
>

%% la macro de projection
\def\psProjection{\def\pst@par{}\pst@object{psProjection}}
\def\psProjection@i{\@ifnextchar({\psProjection@ii}{\psProjection@ii(0.,0.,0.)}}
\def\psProjection@ii(#1,#2,#3){{%
      \use@par
\ifPst@solidmemory
\else
  \begin@ClosedObj
\fi
      \addto@pscode{%
         \tx@optionssolides
         SolidesDict begin
         \tx@psProjection
         /CX 0 def
         /CY 0 def
         /CZ 0 def
         /xorigine #1 def
         /yorigine #2 def
         /zorigine #3 def
         % nature du solide : texte, chemin, courbe
         proj-\psk@solides@object\space
         end
      }%<- fin du code ps
         \psk@fillstyle
         \pst@stroke
\ifPst@solidmemory
\else
  \end@ClosedObj
\fi
  }}



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \psLineIIID est
%% adapté de la macro \pstThreeDLine du package pst-3dplot (H.Voss)
%% http://tug.ctan.org/tex-archive/graphics/pstricks/contrib/pst-3dplot
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\def\cartesianIIID@coor#1,#2,#3,#4\@nil{\edef\pst@coor{#1 #2 #3 }}
\def\NormalIIIDCoor{%
  \def\pst@@getcoor##1{\pst@expandafter\cartesianIIID@coor{##1}, ,\@nil}%
  \def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@cartesian}%
}%

\def\psLineIIID{\NormalIIIDCoor\pst@object{lineIIID}}
\def\lineIIID@i{%
  \pst@killglue%
  \pst@getarrows{%
    \begin@OpenObj%
      \pst@getcoors[\lineIIID@ii%
  }%
}
\def\lineIIID@ii{%
  \addto@pscode{%
    \tx@optionssolides
    SolidesDict begin
   counttomark
  /n exch def /n3 n 3 div cvi def
  n3 {
    n -3 roll
      3dto2d
      xunit mul exch xunit mul exch
    /n n 1 sub def
  } repeat
    end
    \pst@cp\space \psline@iii\space \tx@Line
  }%
  \end@OpenObj%
  \ignorespaces%
  \SpecialCoor%
}

\def\psPolygonIIID{\NormalIIIDCoor\pst@object{polygonIIID}}
\def\polygonIIID@i{%
  \pst@killglue%
  \pst@getarrows{%
    \begin@ClosedObj%
      \pst@getcoors[\polygonIIID@ii%
  }%
}
\def\polygonIIID@ii{%
  \addto@pscode{%
    \tx@optionssolides
    SolidesDict begin
   counttomark
  /n exch def /n3 n 3 div cvi def
  n3 {
    n -3 roll
      3dto2d
      xunit mul exch xunit mul exch
    /n n 1 sub def
  } repeat
    end
    \pst@cp\space \psline@iii\space \tx@Polygon
  }%
  \end@ClosedObj%
  \ignorespaces%
  \SpecialCoor%
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\catcode`\@=\PstAtCode\relax


\endinput
