Povray code-j-aug.inc

```
/\* This program is free software: you can redistribute it and/or modify it
 \* under the terms of the GNU General Public License as published by the Free
 \* Software Foundation, either version 3 of the License, or (at your option)
 \* any later version.
 \*
 \* This program is distributed in the hope that it will be useful, but WITHOUT
 \* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 \* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 \* more details.
 \*
 \* You should have received a copy of the GNU General Public License along with
 \* this program. If not, see <http://www.gnu.org/licenses/>
 \*/

/\* File for the prismatic augmented Johnson polyhedra \*/

/\* Parameters:
 \* TopAugment
 \* BottomAugment:
 \* The cap and cup (resp.) of the polyhedron, as follows:
 \* 0 - simple polygon (default)
 \* 1 - pyramid
 \* 2 - cupola
 \* 3 - rotunda
 \*
 \* NumPrismSides:
 \* The number of sides of the central prism/antiprism/polygon
 \*
 \* MiddleBand:
 \* The central band, as follows:
 \* 0 - no band
 \* 1 - prism (default)
 \* 2 - antiprism
 \*
 \* Gyrate:
 \* Rotate the cup by pi/NumPrismSize radians
 \*/

#include "poly-textures.inc"

#ifndef (TopAugment)
 #declare TopAugment = 0;
#end
#ifndef (BottomAugment)
 #declare BottomAugment = 0;
#end
#ifndef (MiddleBand)
 #declare MiddleBand = 1;
#end

#debug "TA: "
#switch (TopAugment)
 #case (0)
 #debug "Omitted"
 #break
 #case (1)
 #debug "Pyramid"
 #break
 #case (2)
 #debug "Cupola "
 #break
 #case (3)
 #debug "Rotunda"
 #break
 #else
 #debug str(TopAugment, 7, 0)
#end
#debug ", BA: "
#switch (BottomAugment)
 #case (0)
 #debug "Omitted"
 #break
 #case (1)
 #debug "Pyramid"
 #break
 #case (2)
 #debug "Cupola "
 #break
 #case (3)
 #debug "Rotunda"
 #break
 #else
 #debug str(TopAugment, 7, 0)
#end
#debug concat(", NPS: ", str(NumPrismSides, 2, 0), ", MB: ")
#switch (MiddleBand)
 #case (0)
 #debug "Omitted "
 #break
 #case (1)
 #debug "Prism "
 #break
 #case (2)
 #debug "Antiprism"
 #ifdef (Gyrate)
 #error "Gyrate antiprisms are an anachronism."
 #end
 #break
 #else
 #debug str(MiddleBand, 9, 0)
#end
#ifdef (Gyrate)
 #debug ", Gyrate\n"
#else
 #debug ", Nongyrate\n"
#end

#declare Phi = (1 + sqrt(5)) / 2;
#declare Phi2 = Phi \* Phi;
#declare Phi3 = Phi \* Phi2;
#declare Phi4 = Phi2 \* Phi2;
#declare Phi7 = Phi3 \* Phi4;

#local BandTexture1 = 0;
#local BandTexture2 = 1;
#local AugmentTexture1 = 2;
#local AugmentTexture2 = 3;
#local AugmentTextureEnd = 4;

#local PolyCircumradius = 1 / sin(pi / NumPrismSides);
#local PolyInradius = 1 / tan(pi / NumPrismSides);
#local PolyArea = NumPrismSides \* PolyInradius;
#local SemiPrismSides = NumPrismSides / 2;

// Cap
#local NumCapV = 0;
#local NumCapE = 0;
#local NumCapFF = 1;
#local CapVol = 0;
#local CapCentreOfGravity = 0;
#local CapHeight = 0;

#switch (TopAugment)
 #case (0)
 #break
 #case (1)
 #declare NumCapV = 1;
 #declare NumCapE = NumPrismSides;
 #declare NumCapFF = NumPrismSides;
 #declare CapHeight = sqrt(4 - PolyCircumradius \* PolyCircumradius);
 #declare CapVol = PolyArea \* CapHeight / 3;
 #declare CapCentreOfGravity = CapHeight / 4;
 #break
 #case (2)
 #if (mod(NumPrismSides, 2) = 1)
 #error concat("For a cupola, the number of prism sides must be even. ",
 "Got ", str(NumPrismSides, 1, 0))
 #end
 #declare NumCapV = SemiPrismSides;
 #if (NumPrismSides = 4)
 #declare NumCapE = 5;
 #declare NumCapFF = 4;
 #else
 #declare NumCapE = 3 \* SemiPrismSides;
 #declare NumCapFF = NumPrismSides + 1;
 #end
 #local SemiPolyCircumradius = 1 / sin(pi / SemiPrismSides);
 #local SemiPolyInradius = 1 / tan(pi / SemiPrismSides);
 #local SemiPolyArea = SemiPrismSides \* SemiPolyInradius;
 #declare CapHeight = sqrt(4 - SemiPolyCircumradius \* SemiPolyCircumradius);
 // Cap composed of 1 n/2-prism, 1 n/2-pyramid and n/2 right-trangular
 // prisms.
 #local PrismVol = SemiPolyArea \* CapHeight;
 #local PyramidVol = SemiPolyArea \* CapHeight / 3;
 #local SlantVol = SemiPrismSides \* CapHeight;
 #declare CapVol = PrismVol + PyramidVol + SlantVol;
 #declare CapCentreOfGravity = (PrismVol \* CapHeight / 2 +
 PyramidVol \* CapHeight / 4 +
 SlantVol \* CapHeight / 3) / CapVol;
 #break
 #case (3)
 #if (NumPrismSides != 10)
 #error concat("A rotunda needs 10 sides. Got ",
 str(NumPrismSides, 1, 0))
 #end
 #declare NumCapV = 10;
 #declare NumCapE = 25;
 #declare NumCapFF = 16;
 #declare CapVol = 10 \* sqrt(3) + 6 \* sqrt(25 + 10 \* sqrt(5));
 #local TriArea = sqrt(3);
 #local PentArea = sqrt(Phi3 \* sqrt(125));
 #local TopTriHeight = 2 \* sqrt(Phi7 / sqrt(5)) / 3;
 #local BottomTriHeight = 2 \* sqrt(Phi / sqrt(5)) / 3;
 #local PentRingHeight = 2 \* sqrt(Phi3 \* sqrt(5)) / 5;
 #declare CapHeight = 2 \* sqrt(Phi3 / sqrt(5));
 #local PyramidCog = 3 / 4;
 #declare CapCentreOfGravity = (5 \* PentRingHeight + CapHeight) \* PentArea;
 #declare CapCentreOfGravity = CapCentreOfGravity +
 5 \* (TopTriHeight + BottomTriHeight) \*
 TriArea;
 #declare CapCentreOfGravity = PyramidCog \* CapCentreOfGravity /
 (6 \* PentArea + 10 \* TriArea);
 #break
 #else
 #error concat("Unknown cap type: ", str(TopAugment, 1, 0))
#end

// Cup
#local NumCupV = 0;
#local NumCupE = 0;
#local NumCupFF = 1;
#local CupVol = 0;
#local CupCentreOfGravity = 0;
#local CupHeight = 0;

#switch (BottomAugment)
 #case (0)
 #break
 #case (1)
 #declare NumCupV = 1;
 #declare NumCupE = NumPrismSides;
 #declare NumCupFF = NumPrismSides;
 #declare CupHeight = sqrt(4 - PolyCircumradius \* PolyCircumradius);
 #declare CupVol = PolyArea \* CupHeight / 3;
 #declare CupCentreOfGravity = CupHeight / 4;
 #break
 #case (2)
 #if (mod(NumPrismSides, 2) = 1)
 #error concat("For a cupola, the number of prism sides must be even. ",
 "Got ", str(NumPrismSides, 1, 0))
 #end
 #declare NumCupV = SemiPrismSides;
 #if (NumPrismSides = 4)
 #declare NumCupE = 5;
 #declare NumCupFF = 4;
 #else
 #declare NumCupE = 3 \* SemiPrismSides;
 #declare NumCupFF = NumPrismSides + 1;
 #end
 #local SemiPolyCircumradius = 1 / sin(pi / SemiPrismSides);
 #local SemiPolyInradius = 1 / tan(pi / SemiPrismSides);
 #local SemiPolyArea = SemiPrismSides \* SemiPolyInradius;
 #declare CupHeight = sqrt(4 - SemiPolyCircumradius \* SemiPolyCircumradius);
 // Cup composed of 1 n/2-prism, 1 n/2-pyramid and n/2 right-trangular
 // prisms.
 #local PrismVol = SemiPolyArea \* CupHeight;
 #local PyramidVol = SemiPolyArea \* CupHeight / 3;
 #local SlantVol = SemiPrismSides \* CupHeight;
 #declare CupVol = PrismVol + PyramidVol + SlantVol;
 #declare CupCentreOfGravity = (PrismVol \* CupHeight / 2 +
 PyramidVol \* CupHeight / 4 +
 SlantVol \* CupHeight / 3) / CupVol;
 #break
 #case (3)
 #if (NumPrismSides != 10)
 #error concat("A rotunda needs 10 sides. Got ",
 str(NumPrismSides, 1, 0))
 #end
 #declare NumCupV = 10;
 #declare NumCupE = 25;
 #declare NumCupFF = 16;
 #declare CupVol = 10 \* sqrt(3) + 6 \* sqrt(25 + 10 \* sqrt(5));
 #local TriArea = sqrt(3);
 #local PentArea = sqrt(Phi3 \* sqrt(125));
 #local TopTriHeight = 2 \* sqrt(Phi7 / sqrt(5)) / 3;
 #local BottomTriHeight = 2 \* sqrt(Phi / sqrt(5)) / 3;
 #local PentRingHeight = 2 \* sqrt(Phi3 \* sqrt(5)) / 5;
 #declare CupHeight = 2 \* sqrt(Phi3 / sqrt(5));
 #local PyramidCog = 3 / 4;
 #declare CupCentreOfGravity = (5 \* PentRingHeight + CupHeight) \* PentArea;
 #declare CupCentreOfGravity = CupCentreOfGravity +
 5 \* (TopTriHeight + BottomTriHeight) \*
 TriArea;
 #declare CupCentreOfGravity = PyramidCog \* CupCentreOfGravity /
 (6 \* PentArea + 10 \* TriArea);
 #break
 #else
 #error concat("Unknown cup type: ", str(BottomAugment, 1, 0))
#end

// Band
#local NumBandV = 2 \* NumPrismSides;
#local NumBandE = 3 \* NumPrismSides;
#local NumBandFF = NumPrismSides;
#local BandVol = 2 \* PolyArea;
#local BandCentreOfGravity = 1;
#local BandHeight = 2;

#switch (MiddleBand)
 #case (0)
 #declare NumBandV = NumPrismSides;
 #declare NumBandE = NumPrismSides;
 #declare NumBandFF = 0;
 #declare BandVol = 0;
 #declare BandCentreOfGravity = 0;
 #declare BandHeight = 0;
 #break;
 #case (2)
 #declare NumBandV = 2 \* NumPrismSides;
 #declare NumBandE = 4 \* NumPrismSides;
 #declare NumBandFF = 2 \* NumPrismSides;
 #local DeltaRadius = PolyCircumradius - PolyInradius;
 #local BandHeight = sqrt(3 - DeltaRadius \* DeltaRadius);
 // See en.wikipedia.org/wiki/Antiprism#Volume\_and\_surface\_area accessed
 // 2021-06-01
 #local Cos = cos(pi / 2 / NumPrismSides);
 #local Radical = sqrt(4 \* Cos \* Cos - 1);
 #local Numer = NumPrismSides \* Radical \* sin(3 \* pi / 2 / NumPrismSides);
 #local Denom = 12 / PolyCircumradius / PolyCircumradius;
 #declare BandVol = Numer / Denom;
 #declare BandCentreOfGravity = BandHeight / 2;
#end

#local CapVerticesStart = 0;
#local CupVerticesStart = CapVerticesStart + NumCapV;
#local BandVerticesStart = CupVerticesStart + NumCupV;
#local BandBottomStart = BandVerticesStart + NumPrismSides;
#if (MiddleBand = 0)
 #declare BandBottomStart = BandVerticesStart;
#end
#declare NumVertices = BandVerticesStart + NumBandV;
#declare Vertices = array[NumVertices];

#local CapEdgesStart = 0;
#local CupEdgesStart = CapEdgesStart + NumCapE;
#local BandEdgesStart = CupEdgesStart + NumCupE;
#declare NumEdges = BandEdgesStart + NumBandE;
#declare Edges = array[NumEdges][2];

#local CapFullFacesStart = 0;
#local CupFullFacesStart = CapFullFacesStart + NumCapFF;
#local BandFullFacesStart = CupFullFacesStart + NumCupFF;
#declare NumFullFaces = BandFullFacesStart + NumBandFF;
#declare FullFaces = array[NumFullFaces][10];
#declare FullFaceSizes = array[NumFullFaces];
#declare FullFaceTextures = array[NumFullFaces];
#local Volume = CapVol + CupVol + BandVol;
#local Cog = ((CapCentreOfGravity + BandHeight / 2) \* CapVol -
 (CupCentreOfGravity + BandHeight / 2) \* CupVol) / Volume;
#local Theta = 0;
#if (MiddleBand = 2)
 #declare Theta = 2;
#end
#ifdef (Gyrate)
 #declare Theta = Theta + 1;
#end
#declare Theta = pi \* Theta / NumPrismSides;

#local Angle = 0;
#local VertOffset = 0;
#if (MiddleBand = 2)
 #declare Angle = pi / NumPrismSides;
#end
#ifdef (Gyrate)
 #declare Angle = Angle + 2 \* pi / NumPrismSides;
 #declare VertOffset = 1;
#end

// Cap
#switch (TopAugment)
 #case (0) // plane polygon
 #for (V, 0, NumPrismSides - 1)
 #declare FullFaces[CapFullFacesStart][V] = BandVerticesStart + V;
 #end
 #declare FullFaceSizes[CapFullFacesStart] = NumPrismSides;
 #declare FullFaceTexture[CapFullFacesStart] = AugmentTextureEnd;
 #break
 #case (1) // Pyramid
 #declare Vertices[CapVerticesStart] = <0, 0,
 CapHeight + BandHeight / 2 - Cog>;
 #for (V, 0, NumPrismSides - 1, 1)
 #declare Edges[CapEdgesStart + V][0] = BandVerticesStart + V;
 #declare Edges[CapEdgesStart + V][1] = CapVerticesStart;
 #local To = CapFullFacesStart + V;
 #declare FullFaces[To][0] = BandVerticesStart + V;
 #declare FullFaces[To][1] = BandVerticesStart +
 mod(V + 1, NumPrismSides);
 #declare FullFaces[To][2] = CapVerticesStart;
 #declare FullFaceSizes[CapFullFacesStart + V] = 3;
 #if (mod(NumPrismSides, 2) + mod(V, 2) = 0)
 #declare FullFaceTextures[CapFullFacesStart + V] = AugmentTexture2;
 #else
 #declare FullFaceTextures[CapFullFacesStart + V] = AugmentTexture1;
 #end
 #end
 #break
 #case (2) // Cupola
 #local SemiCircumradius = 1 / sin(pi / SemiPrismSides);
 #for (V, 0, SemiPrismSides - 1, 1)
 #local Theta = (2 \* V + 0.5) \* pi / SemiPrismSides;
 #local SemiInradius = 1 / tan(pi / SemiPrismSides);
 #local SlantBase = PolyInradius - SemiInradius;
 #local Height = sqrt(4 - SlantBase \* SlantBase) + BandHeight / 2 - Cog;
 #local To = CapVerticesStart + V;
 #declare Vertices[To] = <SemiCircumradius \* sin(Theta),
 SemiCircumradius \* cos(Theta),
 Height>;
 #declare To = CapEdgesStart + V;
 #declare Edges[To][0] = BandVerticesStart + 2 \* V;
 #declare Edges[To][1] = CapVerticesStart + V;
 #declare To = To + SemiPrismSides;
 #declare Edges[To][0] = BandVerticesStart + 2 \* V + 1;
 #declare Edges[To][1] = CapVerticesStart + V;
 #if (V = 0 | NumPrismSides != 4)
 #declare To = To + SemiPrismSides;
 #declare Edges[To][0] = CapVerticesStart + V;
 #declare Edges[To][1] = CapVerticesStart + mod(V + 1, SemiPrismSides);
 #end
 #declare To = CapFullFacesStart + V;
 #declare FullFaces[To][0] = BandVerticesStart + 2 \* V + 1;
 #declare FullFaces[To][1] = BandVerticesStart +
 mod(2 \* V + 2, NumPrismSides);
 #declare FullFaces[To][2] = CapVerticesStart +
 mod(V + 1, SemiPrismSides);
 #declare FullFaces[To][3] = CapVerticesStart + V;
 #declare FullFaceSizes[To] = 4;
 #declare FullFaceTextures[To] = AugmentTexture1;
 #declare To = To + SemiPrismSides;
 #declare FullFaces[To][0] = BandVerticesStart + 2 \* V;
 #declare FullFaces[To][1] = BandVerticesStart + 2 \* V + 1;
 #declare FullFaces[To][2] = CapVerticesStart + V;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = AugmentTexture2;
 #end
 #if (NumPrismSides != 4)
 #local To = CapFullFacesStart + NumPrismSides;
 #for (V, 0, SemiPrismSides - 1, 1)
 #declare FullFaces[To][V] = CapVerticesStart + V;
 #end
 #declare FullFaceSizes[To] = SemiPrismSides;
 #declare FullFaceTextures[To] = AugmentTextureEnd;
 #end
 #break
 #case (3) // Rotunda
 #local Radius2 = Phi / sin(pi / 5);
 #local Height2 = 2 \* sqrt(Phi/ sqrt(5));
 #local Radius3 = 1 / sin(pi / 5);
 #local Height3 = Height2 \* Phi;
 #for (V, 0, 4, 1)
 #local Theta = (2 \* V + 2.5) \* pi / 5;
 #local To = CapVerticesStart + V;
 #declare Vertices[To] = <Radius2 \* sin(Theta),
 Radius2 \* cos(Theta),
 Height2 + BandHeight / 2 - Cog>;
 #declare Theta = (2 \* V + 1.5) \* pi / 5;
 #local To = To + 5;
 #declare Vertices[To] = <Radius3 \* sin(Theta),
 Radius3 \* cos(Theta),
 Height3 + BandHeight / 2 - Cog>;
 #local To = CapEdgesStart + 2 \* V;
 #declare Edges[To][0] = BandVerticesStart + 2 \* V + 1;
 #declare Edges[To][1] = CapVerticesStart + mod(V + 4, 5);
 #declare Edges[To + 1][0] = BandVerticesStart + mod(2 \* V + 2, 10);
 #declare Edges[To + 1][1] = CapVerticesStart + V;
 #declare Edges[To + 10][0] = CapVerticesStart + mod(V + 4, 5);
 #declare Edges[To + 10][1] = CapVerticesStart + 5 + V;
 #declare Edges[To + 11][0] = CapVerticesStart + V;
 #declare Edges[To + 11][1] = CapVerticesStart + 5 + V;
 #declare To = CapEdgesStart + 20 + V;
 #declare Edges[To][0] = CapVerticesStart + 5 + V;
 #declare Edges[To][1] = CapVerticesStart + 5 + mod(V + 1, 5);
 #declare To = CapFullFacesStart + V;
 #declare FullFaces[To][0] = BandVerticesStart + 2 \* V + 1;
 #declare FullFaces[To][1] = CapVerticesStart + mod(V + 4, 5);
 #declare FullFaces[To][2] = CapVerticesStart + V + 5;
 #declare FullFaces[To][3] = CapVerticesStart + V;
 #declare FullFaces[To][4] = BandVerticesStart + mod(2 \* V + 2, 10);
 #declare FullFaceSizes[To] = 5;
 #declare FullFaceTextures[To] = AugmentTexture1;
 #declare To = To + 5;
 #declare FullFaces[To][0] = BandVerticesStart + mod(2 \* V + 2, 10);
 #declare FullFaces[To][1] = BandVerticesStart + mod(2 \* V + 3, 10);
 #declare FullFaces[To][2] = CapVerticesStart + V;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = AugmentTexture2;
 #declare To = To + 5;
 #declare FullFaces[To][0] = CapVerticesStart + V;
 #declare FullFaces[To][1] = CapVerticesStart + V + 5;
 #declare FullFaces[To][2] = CapVerticesStart + mod(V + 1, 5) + 5;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = AugmentTexture2;
 #end
 #local To = CapFullFacesStart + 15;
 #for (V, 0, 4, 1)
 #declare FullFaces[To][V] = CapVerticesStart + V + 5;
 #end
 #declare FullFaceSizes[To] = 5;
 #declare FullFaceTextures[To] = AugmentTexture1;
#end

// Cup
#switch (BottomAugment)
 #case (0) // plane polygon
 #for (V, 0, NumPrismSides - 1)
 #declare FullFaces[CupFullFacesStart][V] = BandBottomStart + V;
 #end
 #declare FullFaceSizes[CupFullFacesStart] = NumPrismSides;
 #declare FullFaceTextures[CupFullFacesStart] = AugmentTextureEnd;
 #break
 #case (1) // Pyramid
 #declare Vertices[CupVerticesStart] = <0, 0,
 -CupHeight - BandHeight / 2 - Cog>;
 #for (V, 0, NumPrismSides - 1, 1)
 #declare Edges[CupEdgesStart + V][0] = BandBottomStart + V;
 #declare Edges[CupEdgesStart + V][1] = CupVerticesStart;
 #local To = CupFullFacesStart + V;
 #declare FullFaces[To][0] = BandBottomStart + V;
 #declare FullFaces[To][1] = BandBottomStart +
 mod(V + 1, NumPrismSides);
 #declare FullFaces[To][2] = CupVerticesStart;
 #declare FullFaceSizes[CupFullFacesStart + V] = 3;
 #if (mod(NumPrismSides, 2) + mod(V, 2) = 0)
 #declare FullFaceTextures[CupFullFacesStart + V] = AugmentTexture2;
 #else
 #declare FullFaceTextures[CupFullFacesStart + V] = AugmentTexture1;
 #end
 #end
 #break
 #case (2) // Cupola
 #local SemiCircumradius = 1 / sin(pi / SemiPrismSides);
 #for (V, 0, SemiPrismSides - 1, 1)
 #local Theta = (2 \* V + 0.5) \* pi / SemiPrismSides + Angle;
 #local SemiInradius = 1 / tan(pi / SemiPrismSides);
 #local SlantBase = PolyInradius - SemiInradius;
 #local Height = -sqrt(4 - SlantBase \* SlantBase) - BandHeight / 2 - Cog;
 #local To = CupVerticesStart + V;
 #declare Vertices[To] = <SemiCircumradius \* sin(Theta),
 SemiCircumradius \* cos(Theta),
 Height>;
 #declare To = CupEdgesStart + V;
 #declare Edges[To][0] = BandBottomStart + 2 \* V + VertOffset;
 #declare Edges[To][1] = CupVerticesStart + V;
 #declare To = To + SemiPrismSides;
 #declare Edges[To][0] = BandBottomStart +
 mod(2 \* V + 1 + VertOffset, NumPrismSides);
 #declare Edges[To][1] = CupVerticesStart + V;
 #if (V = 0 | NumPrismSides != 4)
 #declare To = To + SemiPrismSides;
 #declare Edges[To][0] = CupVerticesStart + V;
 #declare Edges[To][1] = CupVerticesStart + mod(V + 1, SemiPrismSides);
 #end
 #declare To = CupFullFacesStart + V;
 #declare FullFaces[To][0] = BandBottomStart +
 mod(2 \* V + 1 + VertOffset, NumPrismSides);
 #declare FullFaces[To][1] = BandBottomStart +
 mod(2 \* V + 2 + VertOffset, NumPrismSides);
 #declare FullFaces[To][2] = CupVerticesStart +
 mod(V + 1, SemiPrismSides);
 #declare FullFaces[To][3] = CupVerticesStart + V;
 #declare FullFaceSizes[To] = 4;
 #declare FullFaceTextures[To] = AugmentTexture1;
 #declare To = To + SemiPrismSides;
 #declare FullFaces[To][0] = BandBottomStart + 2 \* V + VertOffset;
 #declare FullFaces[To][1] = BandBottomStart +
 mod(2 \* V + 1 + VertOffset, NumPrismSides);
 #declare FullFaces[To][2] = CupVerticesStart + V;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = AugmentTexture2;
 #end
 #if (NumPrismSides != 4)
 #declare To = CupFullFacesStart + NumPrismSides;
 #for (V, 0, SemiPrismSides - 1, 1)
 #declare FullFaces[To][V] = CupVerticesStart + V;
 #end
 #declare FullFaceSizes[To] = SemiPrismSides;
 #declare FullFaceTextures[To] = AugmentTextureEnd;
 #end
 #break
 #case (3) // Rotunda
 #local Radius2 = Phi / sin(pi / 5);
 #local Height2 = -2 \* sqrt(Phi/ sqrt(5));
 #local Radius3 = 1 / sin(pi / 5);
 #local Height3 = Height2 \* Phi;
 #for (V, 0, 4, 1)
 #local Theta = (2 \* V + 2.5) \* pi / 5 + Angle;
 #local To = CupVerticesStart + V;
 #declare Vertices[To] = <Radius2 \* sin(Theta),
 Radius2 \* cos(Theta),
 Height2 - BandHeight / 2 - Cog>;
 #declare Theta = (2 \* V + 1.5) \* pi / 5 + Angle;
 #local To = To + 5;
 #declare Vertices[To] = <Radius3 \* sin(Theta),
 Radius3 \* cos(Theta),
 Height3 - BandHeight / 2 - Cog>;
 #local To = CupEdgesStart + 2 \* V;
 #declare Edges[To][0] = BandBottomStart +
 mod(2 \* V + 1 + VertOffset, 10);
 #declare Edges[To][1] = CupVerticesStart + mod(V + 4, 5);
 #declare Edges[To + 1][0] = BandBottomStart +
 mod(2 \* V + 2 + VertOffset, 10);
 #declare Edges[To + 1][1] = CupVerticesStart + V;
 #declare Edges[To + 10][0] = CupVerticesStart + mod(V + 4, 5);
 #declare Edges[To + 10][1] = CupVerticesStart + 5 + V;
 #declare Edges[To + 11][0] = CupVerticesStart + V;
 #declare Edges[To + 11][1] = CupVerticesStart + 5 + V;
 #declare To = CupEdgesStart + 20 + V;
 #declare Edges[To][0] = CupVerticesStart + 5 + V;
 #declare Edges[To][1] = CupVerticesStart + 5 + mod(V + 1, 5);
 #declare To = CupFullFacesStart + V;
 #declare FullFaces[To][0] = BandBottomStart +
 mod(2 \* V + 1 + VertOffset, 10);
 #declare FullFaces[To][1] = CupVerticesStart + mod(V + 4, 5);
 #declare FullFaces[To][2] = CupVerticesStart + V + 5;
 #declare FullFaces[To][3] = CupVerticesStart + V;
 #declare FullFaces[To][4] = BandBottomStart +
 mod(2 \* V + 2 + VertOffset, 10);
 #declare FullFaceSizes[To] = 5;
 #declare FullFaceTextures[To] = AugmentTexture1;
 #declare To = To + 5;
 #declare FullFaces[To][0] = BandBottomStart +
 mod(2 \* V + 2 + VertOffset, 10);
 #declare FullFaces[To][1] = BandBottomStart +
 mod(2 \* V + 3 + VertOffset, 10);
 #declare FullFaces[To][2] = CupVerticesStart + V;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = AugmentTexture2;
 #declare To = To + 5;
 #declare FullFaces[To][0] = CupVerticesStart + V;
 #declare FullFaces[To][1] = CupVerticesStart + V + 5;
 #declare FullFaces[To][2] = CupVerticesStart + mod(V + 1, 5) + 5;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = AugmentTexture2;
 #end
 #local To = CupFullFacesStart + 15;
 #for (V, 0, 4, 1)
 #declare FullFaces[To][V] = CupVerticesStart + V + 5;
 #end
 #declare FullFaceSizes[To] = 5;
 #declare FullFaceTextures[To] = AugmentTexture1;
#end

// Band
#for (V, 0, NumPrismSides - 1, 1)
 #local To = BandVerticesStart + V;
 #local Theta = V \* pi / SemiPrismSides;
 #declare Vertices[To] = <PolyCircumradius \* sin(Theta),
 PolyCircumradius \* cos(Theta),
 BandHeight / 2 - Cog>;
 #declare To = BandEdgesStart + V;
 #declare Edges[To][0] = BandVerticesStart + V;
 #declare Edges[To][1] = BandVerticesStart + mod(V + 1, NumPrismSides);
#end
#if (MiddleBand != 0)
 #local Angle = 0;
 #if (MiddleBand = 2)
 #declare Angle = pi / NumPrismSides;
 #end
 #for (V, 0, NumPrismSides - 1, 1)
 #local Theta = 2 \* V \* pi / NumPrismSides + Angle;
 #local To = BandVerticesStart + V + NumPrismSides;
 #declare Vertices[To] = <PolyCircumradius \* sin(Theta),
 PolyCircumradius \* cos(Theta),
 -BandHeight / 2 - Cog>;
 #declare To = BandEdgesStart + NumPrismSides + V;
 #declare Edges[To][0] = BandVerticesStart + NumPrismSides + V;
 #declare Edges[To][1] = BandVerticesStart + NumPrismSides +
 mod(V + 1, NumPrismSides);
 #end
#end
#switch (MiddleBand)
 #case (1)
 #for (I, 0, NumPrismSides - 1, 1)
 #local To = BandEdgesStart + 2 \* NumPrismSides + I;
 #declare Edges[To][0] = BandVerticesStart + I;
 #declare Edges[To][1] = BandVerticesStart + NumPrismSides + I;
 #declare To = BandFullFacesStart + I;
 #declare FullFaces[To][0] = BandVerticesStart + I;
 #declare FullFaces[To][1] = BandVerticesStart +
 mod(I + 1, NumPrismSides);
 #declare FullFaces[To][2] = BandVerticesStart + NumPrismSides +
 mod(I + 1, NumPrismSides);
 #declare FullFaces[To][3] = BandVerticesStart + NumPrismSides + I;
 #declare FullFaceSizes[To] = 4;
 #if (mod(NumPrismSides, 2) + mod(I, 2) = 0)
 #declare FullFaceTextures[To] = BandTexture2;
 #else
 #declare FullFaceTextures[To] = BandTexture1;
 #end
 #end
 #break
 #case (2) // Antiprism
 #for (I, 0, NumPrismSides - 1, 1)
 #local To = BandEdgesStart + 2 \* NumPrismSides + I;
 #declare Edges[To][0] = BandVerticesStart + I;
 #declare Edges[To][1] = BandVerticesStart + NumPrismSides + I;
 #declare To = To + NumPrismSides;
 #declare Edges[To][0] = BandVerticesStart + mod(I + 1, NumPrismSides);
 #declare Edges[To][1] = BandVerticesStart + NumPrismSides + I;
 #declare To = BandFullFacesStart + I;
 #declare FullFaces[To][0] = BandVerticesStart + I;
 #declare FullFaces[To][1] = BandVerticesStart +
 mod(I + 1, NumPrismSides);
 #declare FullFaces[To][2] = BandVerticesStart + NumPrismSides + I;
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = BandTexture1;
 #declare To = To + NumPrismSides;
 #declare FullFaces[To][0] = BandVerticesStart + I;
 #declare FullFaces[To][1] = BandVerticesStart + NumPrismSides + I;
 #declare FullFaces[To][2] = BandVerticesStart + NumPrismSides +
 mod(I + NumPrismSides - 1,
 NumPrismSides);
 #declare FullFaceSizes[To] = 3;
 #declare FullFaceTextures[To] = BandTexture2;
 #end
#end

// Triangulate
#declare NumFaces = 0;
#for (F, 0, NumFullFaces - 1, 1)
 #declare NumFaces = NumFaces + FullFaceSizes[F] - 2;
#end
#declare Faces = array[NumFaces][3];
#declare FaceTextureIndex = array[NumFaces];

#local NextFace = -1;
#for (F, 0, NumFullFaces - 1, 1)
 #local Texture = FullFaceTextures[F];
 #for (FF, 1, FullFaceSizes[F] - 2, 1)
 #local To = NextFace + FF;
 #declare Faces[To][0] = FullFaces[F][0];
 #declare Faces[To][1] = FullFaces[F][FF];
 #declare Faces[To][2] = FullFaces[F][FF + 1];
 #declare FaceTextureIndex[To] = Texture;
 #end
 #declare NextFace = NextFace + FullFaceSizes[F] - 2;
#end

// Calculate circumradius
#declare Circumradius = 0;
#for (V, 0, NumVertices - 1, 1)
 #local Len = vlength(Vertices[V]);
 #if (Len > Circumradius)
 #declare Circumradius = Len;
 #end
#end

```