/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* *                                                                                                 * */
/* *   INSTRUCTIONS                                                                                  * */
/* *                                                                                                 * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

/*
//The Master of Puppets Font is easy to use. You may set various options or use the default values. The
//following example demonstrates all you need to do to use the font:

#declare MOP_Gap                 = .14;   //Set the distance between characters (optional, default = .14)
#declare MOP_Space               = .65;   //Set the distance between words      (optional, default = .65)
#declare MOP_FontRadius          = .0625; //Set the radius of the strokes       (optional, default = .0625)
#declare MOP_UseFrenchQuoteMarks = no;    //Use French quote marks              (optional, default = no)

#include "MasterOfPuppetsFont.inc"

CreateMOP_TextObject ("Your text goes here.", MOP_Gap, MOP_Space, MOP_FontRadius)

object {MOP_TextObject texture {YourTextureHere} translate <-MOP_TextObjectWidth / 2, 0, 0>}

//The macro will create a CSG object called "MOP_TextObject" from the string you specify. It will set a
//variable called MOP_TextObjectWidth and the object will extend from x = 0 to x = MOP_TextObjectWidth.
//In the example above the object will be centered horizontally with the base of the characters at y = 0.
//The characters will be scaled equally in all three dimensions to be one unit tall (not including
//ascenders and descenders). The back of the object will be at z = 0 and the front of the object will
//extend into the -z direction.

//A number of special characters are available, which are designated by a letter enclosed in curly
//brackets. The designators and special characters are as follows:

//   {A}   Bullet (round)
//   {B}   Bullet (rectangular)
//   {C}   Bullet (triangular)
//   {D}   Copyright symbol
//   {E}   Left-pointing arrow
//   {F}   Right-pointing arrow
//   {G}   Up-pointing arrow
//   {H}   Down-pointing arrow
//   {I}   Cross
//   {J}   Star
//   {K}   Degree symbol
//   {L}   Smiley
//   {M}   Metallica logo (Sorry, this one doesn't have rounded edges.)

//In general, good values for MOP_FontRadius are > 0 to <= .063. At larger values the "e" will develop
//glitches. At values larger than .0986 the "Q" will develop glitches. Different characters will have
//problems at different radii but most characters will work fine even beyond .1. A value of .0625 best
//matches the font on the Master of Puppets album cover. Since the CreateMOP_TextObject () macro scales
//the characters to be one unit tall, the final, scaled radius will always be less than the specified
//radius.

//Reminder: To use quote marks within a string variable, you must preface the quote marks with a back-
//slash, thusly: \" The same is true for the backslash character itself: type this \\ to get one back-
//slash character.

//Note that the rounded nature of this font is especially suited to metallic and/or shiny, reflective
//textures.

//Advanced instructions:
//----------------------

//In the event that you need to apply different textures to the individual characters in your string, or
//perform some other operation on the individual characters, you can use the following method instead of
//the CreateMOP_TextObject () macro:

#declare MOP_TextObject = object {
   #local CurrentX = 0;
   union {
      object {MOP_Character [MOP_CharacterIndex_P_]    texture {P_Color}    translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_P_]    + MOP_FontRadius * 2 + MOP_Gap;
      object {MOP_Character [MOP_CharacterIndex_O_]    texture {O_Color}    translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_O_]    + MOP_FontRadius * 2 + MOP_Gap;
      object {MOP_Character [MOP_CharacterIndex_V_]    texture {V_Color}    translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_V_]    + MOP_FontRadius * 2 + MOP_Gap;
      object {MOP_Character [MOP_CharacterIndex_DASH_] texture {DASH_Color} translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_DASH_] + MOP_FontRadius * 2 + MOP_Gap;
      object {MOP_Character [MOP_CharacterIndex_R_]    texture {R_Color}    translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_R_]    + MOP_FontRadius * 2 + MOP_Gap;
      object {MOP_Character [MOP_CharacterIndex_a_]    texture {a_Color}    translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_a_]    + MOP_FontRadius * 2 + MOP_Gap;
      object {MOP_Character [MOP_CharacterIndex_y_]    texture {y_Color}    translate CurrentX * x} #local CurrentX = CurrentX + MOP_CharacterWidth [MOP_CharacterIndex_y_]    + MOP_FontRadius * 2 + MOP_Gap;
   } //union
   translate <MOP_FontRadius, MOP_FontRadius, -MOP_FontRadius> //The lower left corner/back of the text object will be at the origin.
   #local S = 1 / (1 + MOP_FontRadius * 2);
   scale <S, S, S>
   #declare MOP_TextObjectWidth = (CurrentX - MOP_Gap) * S;
} //object

object {MOP_TextObject translate <-MOP_TextObjectWidth / 2, 0, 0>}
*/

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* *                                                                                                 * */
/* *   MACROS                                                                                        * */
/* *                                                                                                 * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#macro MeasureCharacter (CharacterIndex_, Shape_, Range_Lower_, Range_Upper_, NSteps_)

   #local I           = CharacterIndex_;
   #local Shape       = Shape_;
   #local Range_Lower = Range_Lower_;
   #local Range_Upper = Range_Upper_;
   #local NSteps      = NSteps_;

   #local Step = (Range_Upper - Range_Lower) / (NSteps - 1);

   #local RayDirection_LeftToRight = x;
   #local RayDirection_RightToLeft = -x;

   #local StepCount = 0;

   #for (CurrentY, Range_Lower, Range_Upper, Step)
      #local RayStartPoint_LeftSide = <-10, CurrentY, -1>;
      #local RayStartPoint_RightSide = <10, CurrentY, -1>;
      #local IntersectionPoint_LeftSide = trace (Shape, RayStartPoint_LeftSide, RayDirection_LeftToRight);
      #if (IntersectionPoint_LeftSide.z != 0) //There's something here...
         #local IntersectionPoint_RightSide = trace (Shape, RayStartPoint_RightSide, RayDirection_RightToLeft);
         #declare MOP_SideDistance_Left [I] [StepCount] = IntersectionPoint_LeftSide.x;
         #declare MOP_SideDistance_Right [I] [StepCount] = MOP_CharacterWidth [I] - IntersectionPoint_RightSide.x + MOP_FontRadius * 2; //"+ MOP_FontRadius * 2" is unique to this project
      #else
         #declare MOP_SideDistance_Left [I] [StepCount] = -1; //Set to -1 if no intersection
         #declare MOP_SideDistance_Right [I] [StepCount] = -1; //Set to -1 if no intersection
         #declare MOP_CharacterFullVertical [I] = no;
      #end //#if
      #local StepCount = StepCount + 1;
   #end //#for

#end //#macro MeasureCharacter

#macro MeasureCharacterToCharacter (CharacterIndex0_, CharacterIndex1_, Range_Lower_, Range_Upper_, NSteps_)

   #local I           = CharacterIndex0_;
   #local J           = CharacterIndex1_;
   #local Range_Lower = Range_Lower_;
   #local Range_Upper = Range_Upper_;
   #local NSteps      = NSteps_;

   #local Step = (Range_Upper - Range_Lower) / (NSteps - 1);

   #local MinimumDistance = 10;

   #local StepCount = 0;

   #for (CurrentY, Range_Lower, Range_Upper, Step)
      #if (MOP_SideDistance_Right [I] [StepCount] != -1 & MOP_SideDistance_Left [J] [StepCount] != -1)
          #local CurrentDistance = MOP_SideDistance_Right [I] [StepCount] + MOP_SideDistance_Left [J] [StepCount];
          #if (CurrentDistance < MinimumDistance)
             #local MinimumDistance = CurrentDistance;
          #end //#if
      #end //#if
      #local StepCount = StepCount + 1;
   #end //#for

   #if (MinimumDistance = 10) //Characters never touch
      -1;
   #else
      abs (MinimumDistance);
   #end //#if

#end //#macro MeasureCharacterToCharacter

#macro XPoint (Point0_, Angle0_, Point1_, Angle1_)

   #local P0 = Point0_;
   #local A0 = Angle0_;
   #local P1 = Point1_;
   #local A1 = Angle1_;

   #local A0 = mod (A0, 360);
   #local A1 = mod (A1, 360);

   #if (P0.x = P1.x & P0.y = P1.y)
      #if (A0 = A1)
         #error "No unique intersection point exists."
      #else
         P0;
         #break
      #end //#if
   #end //#if

   #if (A1 - A0 = 0 | A1 - A0 = 180)
      #error "No unique intersection point exists."
   #end

   #if (P1.x < P0.x)
      #local TPoint = P1;
      #local TAngle = A1;
      #local P1 = P0;
      #local A1 = A0;
      #local P0 = TPoint;
      #local A0 = TAngle;
   #end //#if

   #local XOffset = P0.x;
   #local YOffset = P0.y;

   #local P0 = <0, 0, 0>;
   #local P1 = P1 - <XOffset, YOffset, 0>;

   #if (P1.x = 0)
      #if (P1.y > 0)
         #local Theta = 90;
      #else
         #local Theta = 270;
      #end //#if
   #else
      #local Theta = degrees (atan (P1.y / P1.x));
   #end //#if

   #local R2 = sqrt (P1.x * P1.x + P1.y * P1.y);

   #local A0 = A0 - Theta;
   #local A1 = A1 - Theta;

   #local P1 = <R2, 0, 0>;

   #local A1 = 180 - A1;

   #local A3 = 180 - A0 - A1;

   #local R1 = R2 * sin (radians (A1)) / sin (radians (A3));

   #local A0 = A0 + Theta;

   <R1 * cos (radians (A0)) + XOffset, R1 * sin (radians (A0)) + YOffset, 0>;

#end //#macro XPoint

#macro RightAngleCornerFiller (Quadrant_, P0_, CornerRadius_)

   #local Quadrant     = Quadrant_;
   #local P0           = P0_;
   #local CornerRadius = CornerRadius_;

   object {
      union {
         intersection {
            torus {CornerRadius, R sturm rotate 90 * x translate <CornerRadius, CornerRadius, 0>}
            plane {y, CornerRadius}
            plane {x, CornerRadius}
         } //intersection
         difference {
            box {<0, 0, -R> <CornerRadius, CornerRadius, R>}
            cylinder {<CornerRadius, CornerRadius, -R - .1> <CornerRadius, CornerRadius, R + .1>, CornerRadius}
         } //difference
      } //union
      rotate (Quadrant * 90) * z
      translate P0
   } //object

#end //#macro RightAngleCornerFiller

#macro ArbitraryAngleCornerFiller (P0_, A0_, A1_, R_, CornerRadius_)

   //P0: The point where the two cylinders that are to be connected meet
   //A0: The angle of one of the cylinders (+x = 0, +y = 90, -x = 180, -y = 270)
   //A1: The angle of the other cylinder
   //R:  The radius of the cylinders that are to be connected
   //CornerRadius: The radius of the rounded corner

   #local P0           = P0_;
   #local A0           = A0_;
   #local A1           = A1_;
   #local R            = R_;
   #local CornerRadius = CornerRadius_;

   #local A0 = mod (A0, 360);
   #if (A0 < 0) #local A0 = A0 + 360; #end

   #local A1 = mod (A1, 360);
   #if (A1 < 0) #local A1 = A1 + 360; #end

   #if (A0 > A1)
      #local Temp = A0;
      #local A0   = A1;
      #local A1   = Temp;
   #end //#if

   #local MiddleAngle = (A0 + A1) / 2;

   #local AngleDifference = A1 - A0;

   #if (AngleDifference > 180)
      #local AngleDifference = 360 - AngleDifference;
      #local MiddleAngle = MiddleAngle - 180;
      #local Flip = yes;
   #else
      #local Flip = no;
   #end //#if

   #local L0 = CornerRadius / sin (radians (AngleDifference / 2));

   #local P1 = <P0.x + L0 * cos (radians (MiddleAngle)), P0.y + L0 * sin (radians (MiddleAngle)), 0>;

   object {
      union {
         intersection {
            torus {CornerRadius, R sturm rotate 90 * x}
            plane {y, 0 inverse rotate (A0 + 90) * z}
            plane {y, 0 inverse rotate (A1 + 90) * z}
         } //intersection
         intersection {
            difference {
               box {<-L0 - .1, -L0 - .1, -R> <L0 + .1, L0 + .1, R>}
               cylinder {<0, 0, -R - .1> <0, 0, R + .1>, CornerRadius}
            } //difference
            plane {y, 0 inverse rotate (A0 + 90) * z}
            plane {y, 0 inverse rotate (A1 + 90) * z}
            #if (Flip)
               plane {y, 0 rotate A0 * z translate P0 - P1}
               plane {y, 0 inverse rotate A1 * z translate P0 - P1}
            #else
               plane {y, 0 inverse rotate A0 * z translate P0 - P1}
               plane {y, 0 rotate A1 * z translate P0 - P1}
            #end //#if
         } //intersection
      } //union
      translate P1
   } //object

#end //#macro ArbitraryAngleCornerFiller

#macro ComputeCornerLength (A0_, A1_, R_, CornerRadius_)

   #local A0           = A0_;
   #local A1           = A1_;
   #local R            = R_;
   #local CornerRadius = CornerRadius_;

   #local A0 = mod (A0, 360);
   #if (A0 < 0) #local A0 = A0 + 360; #end

   #local A1 = mod (A1, 360);
   #if (A1 < 0) #local A1 = A1 + 360; #end

   #if (A0 > A1)
      #local Temp = A0;
      #local A0   = A1;
      #local A1   = Temp;
   #end //#if

   #local MiddleAngle = (A0 + A1) / 2;

   #local AngleDifference = A1 - A0;

   #if (AngleDifference > 180)
      #local MiddleAngle = MiddleAngle - 180;
   #end //#if

   #local L0 = CornerRadius / sin (radians (AngleDifference / 2));

   (abs (L0 * cos (radians (MiddleAngle))))

#end //#macro ComputeCornerLength

#macro ArbitraryVerticalBar (X0_, Y0_, Y1_, R_)

   #local X0 = X0_;
   #local Y0 = Y0_;
   #local Y1 = Y1_;
   #local R  = R_;

   union {
      sphere {<X0, Y0, 0>, R}
      sphere {<X0, Y1, 0>, R}
      cylinder {<X0, Y0, 0> <X0, Y1, 0>, R}
   } //union

#end //#macro ArbitraryVerticalBar

#macro ArbitraryHorizontalBar (X0_, X1_, Y0_, R_)

   #local X0 = X0_;
   #local X1 = X1_;
   #local Y0 = Y0_;
   #local R  = R_;

   union {
      sphere {<X0, Y0, 0>, R}
      sphere {<X1, Y0, 0>, R}
      cylinder {<X0, Y0, 0> <X1, Y0, 0>, R}
   } //union

#end //#macro ArbitraryHorizontalBar

#macro ArbitraryDot (PERIOD1_, PERIOD2_, PERIODRadius_, R_)

   #local PERIOD1      = PERIOD1_;
   #local PERIOD2      = PERIOD2_;
   #local PERIODRadius = PERIODRadius_;
   #local R            = R_;

   object {
      union {
         #local PERIODCorner = object {
            intersection {
               torus {PERIODRadius, R sturm rotate 90 * x}
               plane {x, 0}
               plane {y, 0}
            } //intersection
         } //object
         object {PERIODCorner translate <0, PERIODRadius, 0>}
         object {PERIODCorner rotate 90 * z translate <PERIOD1 - PERIODRadius, PERIODRadius, 0>}
         object {PERIODCorner rotate 180 * z translate <PERIOD1 - PERIODRadius, PERIOD2, 0>}
         object {PERIODCorner rotate 270 * z translate <0, PERIOD2, 0>}
         cylinder {<0, 0, 0> <PERIOD1 - PERIODRadius, 0, 0>, R} //Bottom
         cylinder {<PERIOD1, PERIODRadius, 0> <PERIOD1, PERIOD2, 0>, R} //Right
         cylinder {<0, PERIOD2 + PERIODRadius, 0> <PERIOD1 - PERIODRadius, PERIOD2 + PERIODRadius, 0>, R} //Top
         cylinder {<-PERIODRadius, PERIODRadius, 0> <-PERIODRadius, PERIOD2, 0>, R} //Left
         cylinder {<0, 0, -R>, <0, 0, R>, PERIODRadius translate <0, PERIODRadius, 0>}
         cylinder {<0, 0, -R>, <0, 0, R>, PERIODRadius translate <PERIOD1 - PERIODRadius, PERIODRadius, 0>}
         cylinder {<0, 0, -R>, <0, 0, R>, PERIODRadius translate <PERIOD1 - PERIODRadius, PERIOD2, 0>}
         cylinder {<0, 0, -R>, <0, 0, R>, PERIODRadius translate <0, PERIOD2, 0>}
         box {<-PERIODRadius, PERIODRadius, -R> <PERIOD1, PERIOD2, PERIODRadius>}
         box {<0, 0, -R> <PERIOD1 - PERIODRadius, PERIOD2 + PERIODRadius, R>}
      } //union
      translate PERIODRadius * x
   } //object

#end //#macro ArbitraryDot

#macro ArbitraryClosedCircle_SS (Width_, Height_, C1_, C2_, R_)

   #local Width  = Width_;
   #local Height = Height_;
   #local C1     = C1_;
   #local C2     = C2_;
   #local R      = R_;

   sphere_sweep {
      b_spline
      19
      <C1 + C2, 0, 0>, R
      <C1, 0, 0>, R
      <0, C1, 0>, R
      <0, C1 + C2, 0>, R
      <0, Height - C1 - C2, 0>, R
      <0, Height - C1, 0>, R
      <C1, Height, 0>, R
      <C1 + C2, Height, 0>, R
      <Width - C1 - C2, Height, 0>, R
      <Width - C1, Height, 0>, R
      <Width, Height - C1, 0>, R
      <Width, Height - C1 - C2, 0>, R
      <Width, C1 + C2, 0>, R
      <Width, C1, 0>, R
      <Width - C1, 0, 0>, R
      <Width - C1 - C2, 0, 0>, R
      <C1 + C2, 0, 0>, R
      <C1, 0, 0>, R
      <0, C1, 0>, R
   } //sphere_sweep

#end //#macro ArbitraryClosedCircle_SS

#macro ArbitraryCorner_Torus (CornerRadius_, R_, Spin_)

   #local CornerRadius = CornerRadius_;
   #local R            = R_;
   #local Spin         = Spin_;

   #local Corner = object {
      intersection {
         torus {CornerRadius, R sturm rotate 90 * x}
         plane {x, 0}
         plane {y, 0}
      } //intersection
      translate <CornerRadius, CornerRadius, 0>
   } //object

   object {
      union {
         sphere {<CornerRadius, 0, 0>, R}
         sphere {<0, CornerRadius, 0>, R}
         object {Corner}
      } //union
      rotate Spin * z
   } //object

#end //#macro ArbitraryCorner_Torus

#macro ArbitraryRoundCorner (CornerRadius_, R_, A0_, Spin_, MirrorHorizontally_)

   #local CornerRadius       = CornerRadius_;
   #local R                  = R_;
   #local A0                 = A0_;
   #local Spin               = Spin_;
   #local MirrorHorizontally = MirrorHorizontally_;

   object {
      intersection {
         torus {CornerRadius, R sturm rotate 90 * x}
         plane {x, 0}
         plane {y, 0 rotate A0 * z}
      } //intersection
      rotate Spin * z
      #if (MirrorHorizontally)
         rotate 180 * y
      #end //#if
   } //object

#end //#macro ArbitraryRoundCorner

#macro Hump (Width_, Height_, C1_, C2_, R_)

   #local Width  = Width_;
   #local Height = Height_;
   #local C1     = C1_;
   #local C2     = C2_;
   #local R      = R_;

   union {
      intersection {
         sphere_sweep {
            b_spline
            12
            <0, -2, 0>, R
            <0, 0, 0>, R
            <0, Height - C1 - C2, 0>, R
            <0, Height - C1, 0>, R
            <C1, Height, 0>, R
            <C1 + C2, Height, 0>, R
            <Width - C1 - C2, Height, 0>, R
            <Width - C1, Height, 0>, R
            <Width, Height - C1, 0>, R
            <Width, Height - C1 - C2, 0>, R
            <Width, 0, 0>, R
            <Width, -2, 0>, R
         } //sphere_sweep
         plane {y, 0 inverse}
      } //intersection
      sphere {<Width, 0, 0>, R}
   } //union

#end //#macro Hump

#macro CreateMOP_Characters (MOP_FontRadius)

   #local R = MOP_FontRadius;

   #local CornerRadius = R * 1.25;

   #local Height_Lower = .68;

   #local StandardInvisibleOffset = MOP_DefaultKerningDistance;

   #for (I, 0, MOP_NDefinedCharacters - 1)
      #declare MOP_IncludeInvisibleComponent [I] = no;
   #end //#for

   #local QUADRANT1 = 0;
   #local QUADRANT2 = 1;
   #local QUADRANT3 = 2;
   #local QUADRANT4 = 3;

   #local VerticalBar = object {
      union {
         cylinder {<0, 0, 0> <0, 1, 0>, R}
         sphere {<0, 0, 0>, R}
         sphere {<0, 1, 0>, R}
      } //union
   } //object

   #local ijDot = object {
      union {
         sphere {<0, 0, 0>, R}
         sphere {<0, .03, 0>, R}
         cylinder {<0, 0, 0> <0, .03, 0>, R}
      } //union
      translate (1 - .03) * y
   } //object

   #declare MOP_Character [MOP_CharacterIndex_A_] = object {
      #local A2 = .24; //Vertical
      #local A_A0 = 59;
      union {
         #local A1 = 2 * ComputeCornerLength (180 + A_A0, 0, R, CornerRadius); //Width of flat part
         #local A_L0 = 1 / sin (radians (A_A0));
         #local A_L1 = A2 / sin (radians (A_A0));
         #local A_P0 = <A_L0 * cos (radians (A_A0)), A_L0 * sin (radians (A_A0)), 0>;
         #local A_P1 = A_P0 + <A1, 0, 0>;
         #local A_P2 = <A_P1.x + A_P0.x, 0, 0>;
         #local A_P3 = <A_L1 * cos (radians (A_A0)), A2, 0>;
         #local A_P4 = <A_P2.x - A_P3.x, A_P3.y, 0>;
         sphere {<0, 0, 0>, R}
         sphere {A_P0, R}
         sphere {A_P1, R}
         sphere {A_P2, R}
         cylinder {<0, 0, 0> A_P0, R}
         cylinder {A_P0 A_P1, R}
         cylinder {A_P1 A_P2, R}
         cylinder {A_P3 A_P4, R}
         #local TCornerRadius = CornerRadius * 2;
         ArbitraryAngleCornerFiller (A_P0, 180 + A_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (A_P1, 180, -A_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (A_P3, 0, A_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (A_P3, 0, 180 + A_A0, R, TCornerRadius)
         ArbitraryAngleCornerFiller (A_P4, 180, -A_A0, R, TCornerRadius)
         ArbitraryAngleCornerFiller (A_P4, 180, 180 - A_A0, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_A_] = A_P2.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_B_] = object {
      #local B1 = .12;
      #local B2 = 1.13; //Top width
      #local B3 = .2;
      #local B4 = .52; //Vertical
      #local B5 = B2 + .045; //Bottom width
      union {
         object {VerticalBar}
         intersection {
            sphere_sweep { //Top
               b_spline
               12
               <-3, 1, 0>, R
               <0, 1, 0>, R
               <B2 - B1 - B3, 1, 0>, R
               <B2 - B1, 1, 0>, R
               <B2, 1 - B1, 0>, R
               <B2, 1 - B1 - B3, 0>, R
               <B2, B4 + B1 + B3, 0>, R
               <B2, B4 + B1, 0>, R
               <B2 - B1, B4, 0>, R
               <B2 - B1 - B3, B4, 0>, R
               <0, B4, 0>, R
               <-3, B4, 0>, R
            } //sphere_sweep
            plane {x, 0 inverse}
         } //intersection
         intersection {
            sphere_sweep { //Bottom
               b_spline
               12
               <-3, B4, 0>, R
               <0, B4, 0>, R
               <B5 - B1 - B3, B4, 0>, R
               <B5 - B1, B4, 0>, R
               <B5, B4 - B1, 0>, R
               <B5, B4 - B1 - B3, 0>, R
               <B5, B1 + B3, 0>, R
               <B5, B1, 0>, R
               <B5 - B1, 0, 0>, R
               <B5 - B1 - B3, 0, 0>, R
               <0, 0, 0>, R
               <-3, 0, 0>, R
            } //sphere_sweep
            plane {x, 0 inverse}
         } //intersection
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, B4, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, B4, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_B_] = B5;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_C_] = object {
      #local C1 = .12;
      #local C1B = .09;
      #local C1C = .12;
      #local C2 = 1.21; //Width
      #local C3 = .2;
      #local C3B = .14;
      #local C3C = .2;
      #local C4 = .02; //Shorten top width
      #local C5 = .02;
      sphere_sweep {
         b_spline
         18
         <C2 + C5, C1B + C3B + .001, 0>, R
         <C2 + C5, C1B + C3B, 0>, R
         <C2, C1B, 0>, R
         <C2 - C1C, 0, 0>, R
         <C2 - C1C - C3C, 0, 0>, R
         <C1 + C3, 0, 0>, R
         <C1, 0, 0>, R
         <0, C1, 0>, R
         <0, C1 + C3, 0>, R
         <0, 1 - C1 - C3, 0>, R
         <0, 1 - C1, 0>, R
         <C1, 1, 0>, R
         <C1 + C3, 1, 0>, R
         <C2 - C4 - C1C - C3C, 1, 0>, R
         <C2 - C4 - C1C, 1, 0>, R
         <C2 - C4, 1 - C1B, 0>, R
         <C2 - C4 + C5, 1 - C1B - C3B, 0>, R
         <C2 - C4 + C5, 1 - C1B - C3B - .001, 0>, R
      } //sphere_sweep
      #declare MOP_CharacterWidth [MOP_CharacterIndex_C_] = C2 + C5;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_C_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_C_] = object {
         #local C6 = StandardInvisibleOffset;
         #local C7 = MOP_CharacterWidth [MOP_CharacterIndex_C_] - C4 - C6 - .004;
         cylinder {<C7, C1B + C3B - .04, 0> <C7, 1 - C1B - C3B + .04, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_D_] = object {
      #local D1 = .12;
      #local D2 = 1.25; //Width
      #local D3 = .2;
      union {
         object {VerticalBar}
         intersection {
            sphere_sweep {
               b_spline
               12
               <-3, 1, 0>, R
               <0, 1, 0>, R
               <D2 - D1 - D3, 1, 0>, R
               <D2 - D1, 1, 0>, R
               <D2, 1 - D1, 0>, R
               <D2, 1 - D1 - D3, 0>, R
               <D2, D1 + D3, 0>, R
               <D2, D1, 0>, R
               <D2 - D1, 0, 0>, R
               <D2 - D1 - D3, 0, 0>, R
               <0, 0, 0>, R
               <-3, 0, 0>, R
            } //sphere_sweep
            plane {x, 0 inverse}
         } //intersection
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_D_] = D2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_E_] = object {
      #local E1 = .98; //Top and bottom bars
      #local E2 = .945; //Middle bar
      #local E3 = .52; //Vertical
      union {
         object {VerticalBar}
         sphere {<E1, 0, 0>, R}         
         cylinder {<0, 0, 0> <E1, 0, 0>, R}
         sphere {<E2, E3, 0>, R}         
         cylinder {<0, E3, 0> <E2, E3, 0>, R}
         sphere {<E1, 1, 0>, R}         
         cylinder {<0, 1, 0> <E1, 1, 0>, R}
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, E3, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, E3, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_E_] = E1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_E_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_E_] = object {
         #local E4 = StandardInvisibleOffset;
         cylinder {<E2 - E4, 0, 0> <E2 - E4, 1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_F_] = object {
      #local F1 = .95; //Top bar
      #local F2 = .91; //Bottom bar
      #local F3 = .52; //Vertical
      union {
         object {VerticalBar}
         sphere {<F2, F3, 0>, R} 
         cylinder {<0, F3, 0> <F2, F3, 0>, R}
         sphere {<F1, 1, 0>, R}         
         cylinder {<0, 1, 0> <F1, 1, 0>, R}
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, F3, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, F3, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_F_] = F1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_F_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_F_] = object {
         #local F4 = StandardInvisibleOffset;
         cylinder {<F2 - F4, F3, 0> <F2 - F4, 1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_G_] = object {
      #local G1 = .12;
      #local G2 = 1.26; //Width
      #local G3 = .2;
      #local G4 = G1 + G3 + .115; //Vertical, G4 must be > G1 + G3
      #local G5 = G2 / 2 + .04;
      union {
         difference {
            sphere_sweep {
               b_spline
               18
               <G2, 1.3, 0>, R
               <G2, G4, 0>, R
               <G2, G1 + G3, 0>, R
               <G2, G1, 0>, R
               <G2 - G1, 0, 0>, R
               <G2 - G1 - G3, 0, 0>, R
               <G1 + G3, 0, 0>, R
               <G1, 0, 0>, R
               <0, G1, 0>, R
               <0, G1 + G3, 0>, R
               <0, 1 - G1 - G3, 0>, R
               <0, 1 - G1, 0>, R
               <G1, 1, 0>, R
               <G1 + G3, 1, 0>, R
               <G2 - G1 - G3, 1, 0>, R
               <G2 - G1, 1, 0>, R
               <G2, 1 - G1, 0>, R
               <G2, 1 - G1 - G3, 0>, R
            } //sphere_sweep
            box {<G2 - R - .1, G4, -R - .1> <G2 + R + .1, .75, R + .1>}
         } //difference
         ArbitraryHorizontalBar (G5, G2, G4, R)
         RightAngleCornerFiller (QUADRANT3, <G2, G4, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_G_] = G2;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_G_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_G_] = object {
         #local G6 = StandardInvisibleOffset;
         #local G7 = G2 - .02 - G6;
         cylinder {<G7, G4, 0> <G7, .86, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_H_] = object {
      #local H1 = 1.1; //Width
      #local H2 = .52; //Vertical
      union {
         object {VerticalBar}
         object {VerticalBar translate H1 * x}
         cylinder {<0, H2, 0> <H1, H2, 0>, R}
         RightAngleCornerFiller (QUADRANT1, <0, H2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, H2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, <H1, H2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <H1, H2, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_H_] = H1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_I_] = object {
      object {VerticalBar}
      #declare MOP_CharacterWidth [MOP_CharacterIndex_I_] = 0;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_J_] = object {
      #local J1 = .12;
      #local J2 = 1.11; //Width
      #local J3 = .2;
      #local J4 = J1 + J3 + .01; //J4 must be > J1 + J3
      union {
         intersection {
            sphere_sweep {
               b_spline
               11
               <0, J4, 0>, R
               <0, J1 + J3, 0>, R
               <0, J1, 0>, R
               <J1, 0, 0>, R
               <J1 + J3, 0, 0>, R
               <J2 - J1 - J3, 0, 0>, R
               <J2 - J1, 0, 0>, R
               <J2, J1, 0>, R
               <J2, J1 + J3, 0>, R
               <J2, 1, 0>, R
               <J2, 2.5, 0>, R
            } //sphere_sweep
            plane {y, 1}
         } //intersection
         sphere {<J2, 1, 0>, R}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_J_] = J2;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_J_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_J_] = object {
         #local J5 = StandardInvisibleOffset;
         cylinder {<J5, .29, 0> <J5, 1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_K_] = object {
      #local K1 = .29; //Width of horizontal bar
      #local K2 = .52; //Vertical
      #switch (R) //Adjust length of rounded corner
         #range (0, .0845)
            #local K4 = 6.5;
         #break
         #range (.0845, .1)
            #local K4 = 6.5 - (R - .0845) / (.1 - .0845) * 1.8;
         #break
         #range (.1, 999)
            #local K4 = 3;
         #break
      #end //#switch
      #local K_A0 = 30;
      union {
         object {VerticalBar}
         sphere {<K1, K2, 0>, R}
         cylinder {<0, K2, 0> <K1, K2, 0>, R}
         #local K3_Top = sin (radians (90 - K_A0)) * (1 - K2) / sin (radians (K_A0));
         #local K3_Bottom = sin (radians (90 - K_A0)) * K2 / sin (radians (K_A0));
         #local K_L0_Top = sqrt (K3_Top * K3_Top + (1 - K2) * (1 - K2));
         #local K_L0_Bottom = sqrt (K3_Bottom * K3_Bottom + K2 * K2);
         #local Bar_Top = object {
            union {
               cylinder {<0, 0, 0> <K_L0_Top, 0, 0>, R}
               sphere {<K_L0_Top, 0, 0>, R}
            } //union
         } //object
         #local Bar_Bottom = object {
            union {
               cylinder {<0, 0, 0> <K_L0_Bottom, 0, 0>, R}
               sphere {<K_L0_Bottom, 0, 0>, R}
            } //union
         } //object
         object {Bar_Top rotate K_A0 * z translate <K1, K2, 0>}
         object {Bar_Bottom rotate -K_A0 * z translate <K1, K2, 0>}
         #local TCornerRadius = CornerRadius * K4;
         ArbitraryAngleCornerFiller (<K1, K2, 0>, 180, K_A0, R, TCornerRadius)
         ArbitraryAngleCornerFiller (<K1, K2, 0>, 180, -K_A0, R, TCornerRadius)
         ArbitraryAngleCornerFiller (<K1, K2, 0>, K_A0, -K_A0, R, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, K2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, K2, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_K_] = K1 + K3_Bottom;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_K_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_K_] = object {
         #local K3 = StandardInvisibleOffset;
         cylinder {<0, 0, 0> <0, 1, 0>, R translate <K1 + K3_Top - K3, 0, 0>}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_L_] = object {
      #local L1 = 1.03; //Width
      union {
         object {VerticalBar}
         sphere {<L1, 0, 0>, R}
         cylinder {<0, 0, 0> <L1, 0, 0>, R}
         RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_L_] = L1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_L_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_L_] = object {
         #local L2 = StandardInvisibleOffset;
         cylinder {<L1 - L2, 0, 0> <L1 - L2, 1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_M_] = object {
      #local M_A0 = 35;
      union {
         #local M1 = CornerRadius + ComputeCornerLength (180, 270 + M_A0, R, CornerRadius); //Width of flat part
         #local M_L0 = 1 / sin (radians (90 - M_A0));
         #local M_P0 = <M1, 1, 0>;
         #local M_P1 = <M_P0.x + M_L0 * cos (radians (90 - M_A0)), 0, 0>; //Center
         #local M_P2 = <M_P1.x + M_L0 * cos (radians (90 - M_A0)), 1, 0>;
         #local M_P3 = M_P2 + <M1, 0, 0>;
         object {VerticalBar} //Left side
         sphere {M_P0, R}
         cylinder {<0, 1, 0> M_P0, R}
         cylinder {M_P0 M_P1, R}
         sphere {M_P1, R} //Center
         sphere {M_P2, R}
         cylinder {M_P1 M_P2, R}
         cylinder {M_P2 M_P3, R}
         object {VerticalBar translate M_P3.x * x} //Right side
         ArbitraryAngleCornerFiller (M_P0, 180, 270 + M_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (M_P2, 0, 270 - M_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (M_P1, 90 + M_A0, 90 - M_A0, R, CornerRadius) //Center
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, M_P3, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_M_] = M_P3.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_N_] = object {
      #local N_A0 = 44.5;
      union {
         #local N1 = CornerRadius + ComputeCornerLength (180, 270 + N_A0, R, CornerRadius); //Width of flat part
         #local N_L0 = 1 / sin (radians (90 - N_A0));
         #local N_P0 = <0, 1, 0>;
         #local N_P1 = N_P0 + <N1, 0, 0>;
         #local N_P2 = <N_P1.x + N_L0 * cos (radians (90 - N_A0)), 0, 0>;
         #local N_P3 = N_P2 + <N1, 0, 0>;
         object {VerticalBar} //Left side
         object {VerticalBar translate N_P3.x * x} //Right side
         sphere {N_P1, R}
         sphere {N_P2, R}
         cylinder {N_P0 N_P1, R}
         cylinder {N_P1 N_P2, R}
         cylinder {N_P2 N_P3, R}
         ArbitraryAngleCornerFiller (N_P1, 180, 270 + N_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (N_P2, 0, 90 + N_A0, R, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, N_P0, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, N_P3, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_N_] = N_P3.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_O_] = object {
      #local O1 = .15;
      #local O2 = 1.3; //Width
      #local O3 = .2;
      ArbitraryClosedCircle_SS (O2, 1, O1, O3, R)
      #declare MOP_CharacterWidth [MOP_CharacterIndex_O_] = O2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_P_] = object {
      #local P1 = .12;
      #local P2 = 1.1; //Width
      #local P3 = .2;
      #local P4 = .445; //Vertical
      union {
         object {VerticalBar}
         intersection {
            sphere_sweep {
               b_spline
               12
               <-3, 1, 0>, R
               <0, 1, 0>, R
               <P2 - P1 - P3, 1, 0>, R
               <P2 - P1, 1, 0>, R
               <P2, 1 - P1, 0>, R
               <P2, 1 - P1 - P3, 0>, R
               <P2, P4 + P1 + P3, 0>, R
               <P2, P4 + P1, 0>, R
               <P2 - P1, P4, 0>, R
               <P2 - P1 - P3, P4, 0>, R
               <0, P4, 0>, R
               <-3, P4, 0>, R
            } //sphere_sweep
            plane {x, 0 inverse}
         } //intersection
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, P4, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, P4, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_P_] = P2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_Q_] = object {
      #local Q1 = MOP_CharacterWidth [MOP_CharacterIndex_O_]; //Width
      #local Q2 = .26; //Outside length of tail
      #local Q3 = .385; //Inside length of tail
      #switch (R) //Adjust length of flattened portion
         #range (0, .06)
            #local Q4 = .085;
         #break
         #range (.06, .0986)
            #local Q4 = .085 - (R - .06) / (.0986 - .06) * .085;
         #break
         #range (.0986, 999)
            #local Q4 = 0;
         #break
      #end //#switch
      #local Q_A0 = 32;
      union {
         difference {
            object {MOP_Character [MOP_CharacterIndex_O_]}
            box {<Q1 / 2, -R - .1, -R - .1> <Q1 + .1, .5, R + .1>}
         } //difference
         #local QCornerRadius = .28;
         #local Q_P0 = <QCornerRadius * cos (radians (-45)), QCornerRadius * sin (radians (-45)), 0>;
         #local QCorner_Left = ArbitraryRoundCorner (QCornerRadius, R, 45, 0, yes)
         #local QCorner_Right = ArbitraryRoundCorner (QCornerRadius, R, 45, 90, no)
         object {QCorner_Left translate <Q1 - .5 + Q4, QCornerRadius, 0>}
         cylinder {<Q1 / 2, 0, 0> <Q1 - .5 + Q4, 0, 0>, R}
         sphere {<Q1 / 2, 0, 0>, R}
         sphere {<Q1 - .5 + Q4, 0, 0>, R}
         object {QCorner_Right translate <Q1 - QCornerRadius, .5 - Q4, 0>}
         #if (Q4 > 0)
            cylinder {<Q1, .5 - Q4, 0> <Q1, .5, 0>, R}
            sphere {<Q1, .5 - Q4, 0>, R}
         #end //#if
         sphere {<Q1, .5, 0>, R}
         #local Q_P0_Left = Q_P0 + <Q1 - .5 + Q4, QCornerRadius, 0>;
         #local Q_P0_Right = Q_P0 + <Q1 - QCornerRadius, .5 - Q4, 0>;
         cylinder {Q_P0_Left, Q_P0_Right, R}
         #local QTail = object {
            union {
               cylinder {<-Q3, 0, 0> <Q2, 0, 0>, R}
               sphere {<-Q3, 0, 0>, R}
               sphere {<Q2, 0, 0>, R}
            } //union
         } //object
         #local Q_P1 = <(Q_P0_Left.x + Q_P0_Right.x) / 2, (Q_P0_Left.y + Q_P0_Right.y) / 2, 0>;
         object {QTail rotate -Q_A0 * z translate Q_P1}
         ArbitraryAngleCornerFiller (Q_P1, 45, 180 - Q_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (Q_P1, 45, -Q_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (Q_P1, -135, 180 - Q_A0, R, CornerRadius)
         ArbitraryAngleCornerFiller (Q_P1, -135, -Q_A0, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_Q_] = Q_P1.x + Q2 * cos (radians (Q_A0));
   } //object

   #declare MOP_Character [MOP_CharacterIndex_R_] = object {
      #local R1 = .12;
      #local R2 = 1.12; //Top width
      #local R3 = .2;
      #local R4 = .445; //Vertical
      #local R5 = R2 - .015; //Bottom width
      union {
         object {VerticalBar}
         intersection {
            sphere_sweep { //Top
               b_spline
               12
               <-3, 1, 0>, R
               <0, 1, 0>, R
               <R2 - R1 - R3, 1, 0>, R
               <R2 - R1, 1, 0>, R
               <R2, 1 - R1, 0>, R
               <R2, 1 - R1 - R3, 0>, R
               <R2, R4 + R1 + R3, 0>, R
               <R2, R4 + R1, 0>, R
               <R2 - R1, R4, 0>, R
               <R2 - R1 - R3, R4, 0>, R
               <0, R4, 0>, R
               <-3, R4, 0>, R
            } //sphere_sweep
            plane {x, 0 inverse}
         } //intersection
         union {
            intersection {
               sphere_sweep { //Bottom
                  b_spline
                  8
                  <-3, R4, 0>, R
                  <0, R4, 0>, R
                  <R5 - R1 - R3, R4, 0>, R
                  <R5 - R1, R4, 0>, R
                  <R5, R4 - R1, 0>, R
                  <R5, R4 - R1 - R3, 0>, R
                  <R5, 0, 0>, R
                  <R5, -2, 0>, R
               } //sphere_sweep
               plane {x, 0 inverse}
               plane {y, 0 inverse}
            } //intersection
            sphere {<R5, 0, 0>, R}
         } //union
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, R4, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, R4, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_R_] = R2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_S_] = object {
      #local S1 = .12;
      #local S1B = .11;
      #local S1C = .12;
      #local S2 = 1.11; //Top width
      #local S3 = .12;
      #local S3B = .155;
      #local S3C = .2;
      #local S4 = .5; //Vertical
      #local S5 = .01;
      #local S7 = .015; //Additional bottom width
      sphere_sweep {
         b_spline
         26
         <-S5, S1B + S3B + .001, 0>, R
         <-S5, S1B + S3B, 0>, R
         <-S5, S1, 0>, R
         <S1C, 0, 0>, R
         <S1C + S3C, 0, 0>, R
         <S2 + S7 - S1C - S3C, 0, 0>, R
         <S2 + S7 - S1C, 0, 0>, R
         <S2 + S7, S1, 0>, R
         <S2 + S7 + S5, S1 + S3, 0>, R
         <S2 + S7 + S5, S4 - S1 - S3, 0>, R
         <S2 + S7, S4 - S1, 0>, R
         <S2 + S7 - S1C, S4, 0>, R
         <S2 + S7 - S1C - S3C, S4, 0>, R
         <S1C + S3C, S4, 0>, R
         <S1C, S4, 0>, R
         <0, S4 + S1, 0>, R
         <-S5, S4 + S1 + S3, 0>, R
         <-S5, 1 - S1 - S3, 0>, R
         <0, 1 - S1, 0>, R
         <S1C, 1, 0>, R
         <S1C + S3C, 1, 0>, R
         <S2 - S1C - S3C, 1, 0>, R
         <S2 - S1C, 1, 0>, R
         <S2, 1 - S1B, 0>, R
         <S2, 1 - S1B - S3B, 0>, R
         <S2, 1 - S3B - .001, 0>, R
      } //sphere_sweep
      translate S5 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_S_] = S2 + S7 + S5 * 2;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_S_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_S_] = object {
         #local S8 = StandardInvisibleOffset;
         #local S9 = S2 + .01;
         union {
            cylinder {<S8, .24, 0> <S8, .74, 0>, R}
            cylinder {<S9 - S8, .3, 0> <S9 - S8, .78, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_T_] = object {
      #local T1 = 1.17; //Top bar
      union {
         sphere {<T1 / 2, 0, 0>, R}
         cylinder {<T1 / 2, 0, 0> <T1 / 2, 1, 0>, R}
         ArbitraryHorizontalBar (0, T1, 1, R)
         RightAngleCornerFiller (QUADRANT3, <T1 / 2, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <T1 / 2, 1, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_T_] = T1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_U_] = object {
      #local U1 = .12;
      #local U2 = 1.18; //Width
      #local U3 = .2;
      union {
         intersection {
            sphere_sweep {
               b_spline
               12
               <U2, 2, 0>, R
               <U2, 1, 0>, R
               <U2, U1 + U3, 0>, R
               <U2, U1, 0>, R
               <U2 - U1, 0, 0>, R
               <U2 - U1 - U3, 0, 0>, R
               <U1 + U3, 0, 0>, R
               <U1, 0, 0>, R
               <0, U1, 0>, R
               <0, U1 + U3, 0>, R
               <0, 1, 0>, R
               <0, 2, 0>, R
            } //sphere_sweep
            plane {y, 1}
         } //intersection
         sphere {<0, 1, 0>, R}
         sphere {<U2, 1, 0>, R}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_U_] = U2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_V_] = object {
      #local V_A0 = 61;
      union {
         #local V1 = 2 * ComputeCornerLength (180 + V_A0, 0, R, CornerRadius); //Width of flat part
         #local V_L0 = 1 / sin (radians (V_A0));
         #local V2 = V_L0 * cos (radians (V_A0));
         #local V_P0 = <V2, 0, 0>;
         #local V_P1 = V_P0 + <V1, 0, 0>;
         #local V_P2 = <V_P1.x + V2, 1, 0>;
         sphere {<0, 1, 0>, R}
         sphere {V_P0, R}
         sphere {V_P1, R}
         sphere {V_P2, R}
         cylinder {<0, 1, 0> V_P0, R}
         cylinder {V_P0 V_P1, R}
         cylinder {V_P1 V_P2, R}
         ArbitraryAngleCornerFiller (V_P0, 180 - V_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (V_P1, 180, V_A0, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_V_] = V_P2.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_W_] = object {
      #local W_A0 = 21;
      union {
         #local W1 = 2 * ComputeCornerLength (90 + W_A0, 0, R, CornerRadius); //Width of flat part
         #local W_L0 = 1 / sin (radians (90 - W_A0));
         #local W2 = W_L0 * cos (radians (90 - W_A0));
         #local W_P0 = <0, 1, 0>;
         #local W_P1 = <W2, 0, 0>;
         #local W_P2 = W_P1 + <W1, 0, 0>;
         #local W_P3 = <W_P2.x + W2, 1, 0>;
         #local W_P4 = W_P3 + <W1, 0, 0>;
         #local W_P5 = <W_P4.x + W2, 0, 0>;
         #local W_P6 = W_P5 + <W1, 0, 0>;
         #local W_P7 = <W_P6.x + W2, 1, 0>;
         sphere {W_P0, R}
         sphere {W_P1, R}
         sphere {W_P2, R}
         sphere {W_P3, R}
         sphere {W_P4, R}
         sphere {W_P5, R}
         sphere {W_P6, R}
         sphere {W_P7, R}
         cylinder {W_P0 W_P1, R}
         cylinder {W_P1 W_P2, R}
         cylinder {W_P2 W_P3, R}
         cylinder {W_P3 W_P4, R}
         cylinder {W_P4 W_P5, R}
         cylinder {W_P5 W_P6, R}
         cylinder {W_P6 W_P7, R}
         ArbitraryAngleCornerFiller (W_P1, 90 + W_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P2, 90 - W_A0, 180, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P3, 270 - W_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P4, 270 + W_A0, 180, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P5, 90 + W_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P6, 90 - W_A0, 180, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_W_] = W_P7.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_X_] = object {
      #local X1 = .56; //Vertical
      #local X2 = .05; //Top vertical offset
      #local X3 = .1 / R + .05; //CornerRadius multiplier
      #local X_A0 = 44;
      #local X_L0_Bottom = X1 / sin (radians (X_A0));
      #local X_L0_Top = (1 - (X1 - X2)) / sin (radians (X_A0));
      #local X_P0 = <X_L0_Bottom * cos (radians (X_A0)), X_L0_Bottom * sin (radians (X_A0)), 0>;
      #local X_P4 = X_P0 - <0, X2, 0>;
      #local X_P1 = <X_P0.x * 2, 0, 0>;
      #local X_P2 = <X_P4.x - X_L0_Top * cos (radians (X_A0)), 1, 0>;
      #local X_P3 = <X_P4.x + X_L0_Top * cos (radians (X_A0)), 1, 0>;
      #local X_P5 = XPoint (<0, 0, 0>, X_A0, X_P2, -X_A0)
      #local X_P6 = XPoint (X_P1, 180 - X_A0, X_P3, X_A0)
      union {
         sphere {<0, 0, 0>, R} //Bottom left
         intersection {
            cylinder {<0, 0, 0> X_P0, R}
            plane {y, 0 rotate -X_A0 * z translate X_P4}
         } //intersection
         sphere {X_P1, R} //Bottom right
         intersection {
            cylinder {X_P1 X_P0, R}
            plane {y, 0 rotate X_A0 * z translate X_P4}
         } //intersection
         sphere {X_P2, R} //Top left
         intersection {
            cylinder {X_P2 X_P4, R}
            plane {y, 0 inverse rotate X_A0 * z translate X_P0}
         } //intersection
         sphere {X_P3, R} //Top right
         intersection {
            cylinder {X_P3 X_P4, R}
            plane {y, 0 inverse rotate -X_A0 * z translate X_P0}
         } //intersection
         #local TCornerRadius = CornerRadius * X3;
         ArbitraryAngleCornerFiller (X_P0, 180 + X_A0, -X_A0, R, TCornerRadius) //Bottom
         ArbitraryAngleCornerFiller (X_P4, 180 - X_A0, X_A0, R, TCornerRadius) //Top
         ArbitraryAngleCornerFiller (X_P5, 180 - X_A0, 180 + X_A0, R, TCornerRadius) //Left
         ArbitraryAngleCornerFiller (X_P6, X_A0, -X_A0, R, TCornerRadius) //Right
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_X_] = X_P1.x;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_X_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_X_] = object {
         #local X4 = StandardInvisibleOffset;
         union {
            cylinder {<X_P2.x + X4, 0, 0> <X_P2.x + X4, 1, 0>, R}
            cylinder {<X_P3.x - X4, 0, 0> <X_P3.x - X4, 1, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_Y_] = object {
      #local Y1 = .44; //Vertical
      #local Y3 = 1.2; //Width
      #local Y4 = Y3 / 2;
      #local Y_A0 = degrees (atan (Y4 / (1 - Y1)));
      union {
         sphere {<0, 0, 0>, R}
         sphere {<0, Y1, 0>, R}
         cylinder {<0, 0, 0> <0, Y1, 0>, R}
         #local Y_L0 = sqrt (Y4 * Y4 + (1 - Y1) * (1 - Y1));
         #local Bar = object {
            union {
               cylinder {<0, 0, 0> <Y_L0, 0, 0>, R}
               sphere {<Y_L0, 0, 0>, R}
            } //union
         } //object
         object {Bar rotate (90 + Y_A0) * z translate <0, Y1, 0>}
         object {Bar rotate (90 - Y_A0) * z translate <0, Y1, 0>}
         #local TCornerRadius = CornerRadius * 2;
         ArbitraryAngleCornerFiller (<0, Y1, 0>, 90 + Y_A0, 270, R, TCornerRadius)
         ArbitraryAngleCornerFiller (<0, Y1, 0>, 90 - Y_A0, 270, R, TCornerRadius)
         ArbitraryAngleCornerFiller (<0, Y1, 0>, 90 + Y_A0, 90 - Y_A0, R, CornerRadius)
      } //union
      translate Y4 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_Y_] = Y3;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_Z_] = object {
      #local Z1 = 1.15; //Width
      #local Z2 = .03; //Shorten top left
      #local Z3 = .02; //Shorten top right
      #local Z_A0 = degrees (atan (1 / (Z1 - Z3)));
      #local Z_P0 = <Z1, 0, 0>;
      #local Z_P1 = <0, 0, 0>;
      #local Z_P2 = <Z1 - Z3, 1, 0>;
      #local Z_P3 = <Z2, 1, 0>;
      union {
         ArbitraryHorizontalBar (0, Z1, 0, R) //Bottom bar
         ArbitraryHorizontalBar (Z2, Z1 - Z3, 1, R) //Top bar
         cylinder {Z_P1 Z_P2, R}
         ArbitraryAngleCornerFiller (Z_P1, Z_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (Z_P2, 180 + Z_A0, 180, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_Z_] = Z1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_Z_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_Z_] = object {
         #local Z4 = StandardInvisibleOffset;
         union {
            cylinder {<Z2 + Z4, 0, 0> <Z2 + Z4, 1, 0>, R}
            cylinder {<Z1 - Z3 - Z4, 0, 0> <Z1 - Z3 - Z4, 1, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_a_] = object {
      #local V0 = Height_Lower;
      #local V1 = .87; //Width
      #local V2 = .36; //Height of circle
      #local V3 = .03; //Top offset
      #local C1 = .1;
      #local C2 = .2;
      #local C3 = .08;
      #local C4 = .00001;
      #local C5 = .16;
      union {
         sphere_sweep {
            b_spline
            19
            <C3 + C5, 0, 0>, R
            <C3, 0, 0>, R
            <0, C3, 0>, R
            <0, V2 / 2 - C4, 0>, R
            <0, V2 / 2 + C4, 0>, R
            <0, V2 - C3, 0>, R
            <C3, V2, 0>, R
            <C3 + C5, V2, 0>, R
            <V1 - C3 - C5, V2, 0>, R
            <V1 - C3, V2, 0>, R
            <V1, V2 - C3, 0>, R
            <V1, V2 / 2 + C4, 0>, R
            <V1, V2 / 2 - C4, 0>, R
            <V1, C3, 0>, R
            <V1 - C3, 0, 0>, R
            <V1 - C3 - C5, 0, 0>, R
            <C3 + C5, 0, 0>, R
            <C3, 0, 0>, R
            <0, C3, 0>, R
         } //sphere_sweep
         intersection {
            sphere_sweep {
               b_spline
               10
               <V1, -2, 0>, R
               <V1, 0, 0>, R
               <V1, V0 - C1 - C2, 0>, R
               <V1, V0 - C1, 0>, R
               <V1 - C1, V0, 0>, R
               <V1 - C1 - C2, V0, 0>, R
               <V3 + C1 + C2, V0, 0>, R
               <V3 + C1, V0, 0>, R
               <V3, V0 - C1, 0>, R
               <V3, V0 - C1 - C2, 0>, R
            } //sphere_sweep
            plane {y, 0 inverse}
         } //intersection
         sphere {<V1, 0, 0>, R}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_a_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_a_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_a_] = object {
         #local V4 = StandardInvisibleOffset;
         #local V5 = .046;
         cylinder {<V5 + V4, .24, 0> <V5 + V4, .565, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_b_] = object {
      #local V0 = Height_Lower;
      #local V1 = .89; //Width
      #local C1 = .12;
      #local C2 = .2;
      union {
         object {VerticalBar}
         ArbitraryClosedCircle_SS (V1, V0, C1, C2, R)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_b_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_c_] = object {
      #local V0 = Height_Lower;
      #local V1 = .86; //Width
      #local V3 = 0; //Top offset
      #local C1 = .12;
      #local C2 = .2;
      sphere_sweep {
         b_spline
         16
         <V1 + .12, C1 + C2 + .3, 0>, R
         <V1, C1, 0>, R
         <V1 - C1, 0, 0>, R
         <V1 - C1 - C2, 0, 0>, R
         <C1 + C2, 0, 0>, R
         <C1, 0, 0>, R
         <0, C1, 0>, R
         <0, C1 + C2, 0>, R
         <0, V0 - C1 - C2, 0>, R
         <0, V0 - C1, 0>, R
         <C1, V0, 0>, R
         <C1 + C2, V0, 0>, R
         <V1 - V3 - C1 - C2, V0, 0>, R
         <V1 - V3 - C1, V0, 0>, R
         <V1 - V3, V0 - C1, 0>, R
         <V1 - V3, V0 - C1 - C2 - .2, 0>, R
      } //sphere_sweep
      #declare MOP_CharacterWidth [MOP_CharacterIndex_c_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_c_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_c_] = object {
         #local V4 = StandardInvisibleOffset;
         #local V5 = V1 - .02;
         cylinder {<V5 - V4, .17, 0> <V5 - V4, .51, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_d_] = object {
      MOP_Character [MOP_CharacterIndex_b_]
      rotate 180 * y
      translate MOP_CharacterWidth [MOP_CharacterIndex_b_] * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_d_] = MOP_CharacterWidth [MOP_CharacterIndex_b_];
   } //object

   #declare MOP_Character [MOP_CharacterIndex_e_] = object {
      #local V0 = Height_Lower;
      #local V1 = .89; //Width
      #local V2 = .24; //Corner radius
      #local V4 = .36; //Vertical
      #local A0 = 30;
      #local V3 = V2 - V2 * cos (radians (A0)); //Bottom offset
      #local eCorner = object {
         union {
            intersection {
               torus {V2, R sturm rotate 90 * x}
               plane {x, 0 inverse}
               plane {y, 0 rotate -A0 * z}
            } //intersection
            sphere {<V2 * cos (radians (-A0)), V2 * sin (radians (-A0)), 0>, R}
         } //union
         translate <-V2, V2, 0>
      } //object
      union {
         sphere {<V1 - V2 + V3, 0, 0>, R}
         sphere {<V1, V4, 0>, R}
         cylinder {<V2, 0, 0> <V1 - V2 + V3, 0, 0>, R}
         cylinder {<0, V2, 0> <0, V0 - V2, 0>, R}
         cylinder {<V2, V0, 0> <V1 - V2, V0, 0>, R}
         cylinder {<V1, V4, 0> <V1, V0 - V2, 0>, R}
         cylinder {<0, V4, 0> <V1, V4, 0>, R}
         object {eCorner translate <V1 + V3, 0, 0>}
         object {ArbitraryCorner_Torus (V2, R, 0)}
         object {ArbitraryCorner_Torus (V2, R, -90) translate <0, V0, 0>}
         object {ArbitraryCorner_Torus (V2, R, -180) translate <V1, V0, 0>}
         RightAngleCornerFiller (QUADRANT2, <V1, V4, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, V4, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, V4, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_e_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_e_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_e_] = object {
         #local V5 = StandardInvisibleOffset;
         cylinder {<V1 - V5, V2 * sin (radians (A0)), 0> <V1 - V5, V4, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_f_] = object {
      #local V0 = Height_Lower; //Vertical
      #local V1 = .15; //Corner radius
      #local V2 = .18; //Left width
      #local V3 = .38; //Right width
      union {
         sphere {<0, 0, 0>, R}
         sphere {<V3, 1, 0>, R}
         cylinder {<0, 0, 0> <0, 1 - V1, 0>, R}
         cylinder {<V1, 1, 0> <V3, 1, 0>, R}
         object {ArbitraryCorner_Torus (V1, R, -90) translate 1 * y}
         ArbitraryHorizontalBar (-V2, V3, V0, R)
         RightAngleCornerFiller (QUADRANT1, <0, V0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, <0, V0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <0, V0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, V0, 0>, CornerRadius)
      } //union
      translate V2 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_f_] = V2 + V3;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_f_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_f_] = object {
         #local V4 = StandardInvisibleOffset;
         cylinder {<V3 + V2 - V4, V0, 0> <V3 + V2 - V4, 1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_g_] = object {
      #local V0 = Height_Lower;
      #local V1 = .89; //Width
      #local V3 = .04; //Vertical circle offset
      #local V5 = .01; //Horizontal offset
      #local V6 = -.28; //Descender distance
      #local C1 = .12;
      #local C2 = .2;
      union {
         intersection {
            sphere_sweep {
               b_spline
               10
               <V1, V0 + 2, 0>, R
               <V1, V0, 0>, R
               <V1, V6 + C1 + C2, 0>, R
               <V1, V6 + C1, 0>, R
               <V1 - C1, V6, 0>, R
               <V1 - C1 - C2, V6, 0>, R
               <V5 + C1 + C2, V6, 0>, R
               <V5 + C1, V6, 0>, R
               <V5, V6 + C1, 0>, R
               <V5, V6 + C1 + C2, 0>, R
            } //sphere_sweep
            plane {y, V0}
         } //intersection
         sphere {<V1, V0, 0>, R}
         object {ArbitraryClosedCircle_SS (V1, V0 - V3, C1, C2, R) translate V3 * y}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_g_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_g_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_g_] = object {
         #local V4 = StandardInvisibleOffset;
         #local V7 = .03;
         cylinder {<V7 + V4, -.145, 0> <V7 + V4, .25, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_h_] = object {
      #local V0 = Height_Lower;
      #local V1 = .85; //Width
      #local C1 = .12;
      #local C2 = .2;
      union {
         object {VerticalBar}
         Hump (V1, V0, C1, C2, R)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_h_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_i_] = object {
      #local V0 = Height_Lower;
      union {
         ArbitraryVerticalBar (0, 0, V0, R)
         object {ijDot}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_i_] = 0;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_i_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_i_] = object {
         cylinder {<0, V0, 0> <0, 1 - .03, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_j_] = object {
      #local V0 = Height_Lower;
      #local V1 = -.28; //Descender distance (from "g")
      #local V2 = .13; //Corner radius
      union {
         ArbitraryVerticalBar (0, V1 + V2, V0, R)
         object {ijDot}
         object {ArbitraryCorner_Torus (V2, R, -270) translate V1 * y}
      } //union
      translate V2 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_j_] = V2;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_j_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_j_] = object {
         cylinder {<V2, V0, 0> <V2, 1 - .03, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_k_] = object {
      #local V0 = Height_Lower;
      #local K1 = .21; //Width of horizontal bar
      #local K2 = .36; //Vertical
      #switch (R) //Adjust length of rounded corner
         #range (0, .055)
            #local K4 = 6.5;
         #break
         #range (.055, .0625)
            #local K4 = 5.45;
         #break
         #range (.0625, .08)
            #local K4 = 3.55;
         #break
         #range (.08, .1)
            #local K4 = 2.2;
         #break
         #range (.1, .12)
            #local K4 = 1.27;
         #break
         #range (.12, 999)
            #local K4 = -1;
         #break
      #end //#switch
      #local K_A0 = 33;
      union {
         object {VerticalBar}
         sphere {<K1, K2, 0>, R}
         cylinder {<0, K2, 0> <K1, K2, 0>, R}
         #local K3_Top = sin (radians (90 - K_A0)) * (V0 - K2) / sin (radians (K_A0));
         #local K3_Bottom = sin (radians (90 - K_A0)) * K2 / sin (radians (K_A0));
         #local K_L0_Top = sqrt (K3_Top * K3_Top + (V0 - K2) * (V0 - K2));
         #local K_L0_Bottom = sqrt (K3_Bottom * K3_Bottom + K2 * K2);
         #local Bar_Top = object {
            union {
               cylinder {<0, 0, 0> <K_L0_Top, 0, 0>, R}
               sphere {<K_L0_Top, 0, 0>, R}
            } //union
         } //object
         #local Bar_Bottom = object {
            union {
               cylinder {<0, 0, 0> <K_L0_Bottom, 0, 0>, R}
               sphere {<K_L0_Bottom, 0, 0>, R}
            } //union
         } //object
         object {Bar_Top rotate K_A0 * z translate <K1, K2, 0>}
         object {Bar_Bottom rotate -K_A0 * z translate <K1, K2, 0>}
         #if (R <= .12)
            #local TCornerRadius = CornerRadius * K4;
            ArbitraryAngleCornerFiller (<K1, K2, 0>, 180, K_A0, R, TCornerRadius)
            ArbitraryAngleCornerFiller (<K1, K2, 0>, 180, -K_A0, R, TCornerRadius)
         #end //#if
         ArbitraryAngleCornerFiller (<K1, K2, 0>, K_A0, -K_A0, R, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, K2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, <0, K2, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_k_] = K1 + K3_Bottom;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_k_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_k_] = object {
         #local K5 = StandardInvisibleOffset;
         intersection {
            cylinder {<0, 0, 0> <0, 1, 0>, R translate <K1 + K3_Top - K5, 0, 0>}
            plane {y, 0 rotate K_A0 * z translate <K1, K2, 0>}
            plane {y, 0 inverse rotate -K_A0 * z translate <K1, K2, 0>}
         } //intersection
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_l_] = object {
      object {VerticalBar}
      #declare MOP_CharacterWidth [MOP_CharacterIndex_l_] = 0;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_m_] = object {
      #local V0 = Height_Lower;
      #local V1 = .77; //Width
      #local C1 = .12;
      #local C2 = .2;
      union {
         ArbitraryVerticalBar (0, 0, V0, R)
         Hump (V1, V0, C1, C2, R)
         object {Hump (V1, V0, C1, C2, R) translate V1 * x}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_m_] = V1 * 2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_n_] = object {
      #local V0 = Height_Lower;
      #local V1 = .85; //Width
      #local C1 = .12;
      #local C2 = .2;
      union {
         ArbitraryVerticalBar (0, 0, V0, R)
         Hump (V1, V0, C1, C2, R)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_n_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_o_] = object {
      #local V0 = Height_Lower;
      #local V1 = .94; //Width
      #local C1 = .12;
      #local C2 = .2;
      ArbitraryClosedCircle_SS (V1, V0, C1, C2, R)
      #declare MOP_CharacterWidth [MOP_CharacterIndex_o_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_p_] = object {
      #local V0 = Height_Lower;
      #local V1 = .89; //Width
      #local V3 = -.28; //Descender distance (from "g")
      #local C1 = .12;
      #local C2 = .2;
      union {
         ArbitraryVerticalBar (0, V3, V0, R)
         ArbitraryClosedCircle_SS (V1, V0, C1, C2, R)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_p_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_q_] = object {
      MOP_Character [MOP_CharacterIndex_p_]
      rotate 180 * y
      translate MOP_CharacterWidth [MOP_CharacterIndex_p_] * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_q_] = MOP_CharacterWidth [MOP_CharacterIndex_p_];
   } //object

   #declare MOP_Character [MOP_CharacterIndex_r_] = object {
      #local V0 = Height_Lower;
      #local V1 = .7; //Width
      #local C1 = .12;
      #local C2 = .2;
      union {
         ArbitraryVerticalBar (0, 0, V0, R)
         intersection {
            sphere_sweep {
               b_spline
               11
               <0, -2, 0>, R
               <0, 0, 0>, R
               <0, V0 - C1 - C2, 0>, R
               <0, V0 - C1, 0>, R
               <C1, V0, 0>, R
               <C1 + C2, V0, 0>, R
               <V1 - C1 - C2, V0, 0>, R
               <V1 - C1, V0, 0>, R
               <V1, V0 - C1, 0>, R
               <V1, V0 - C1 - C2, 0>, R
               <V1, V0 - C1 - .02, 0>, R
            } //sphere_sweep
            plane {y, 0 inverse}
         } //intersection
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_r_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_s_] = object {
      #local V0 = Height_Lower;
      #local V1 = .87; //Width
      #local V2 = .34; //Vertical
      #local V3 = .01; //Left top indent
      #local V4 = .02; //Right top indent
      #local V6 = V2 / 2;
      #local V7 = (V2 + V0) / 2;
      #local C1 = .08;
      #local C2 = .16;
      #local C3 = .00001;
      sphere_sweep {
         b_spline
         25
         <0, C1 + .11, 0>, R
         <0, C1 + .1, 0>, R
         <0, C1, 0>, R
         <C1, 0, 0>, R
         <C1 + C2, 0, 0>, R
         <V1 - C1 - C2, 0, 0>, R
         <V1 - C1, 0, 0>, R
         <V1, C1, 0>, R
         <V1, V6 - C3, 0>, R
         <V1, V6 + C3, 0>, R
         <V1, V2 - C1, 0>, R
         <V1 - C1, V2, 0>, R
         <V1 - C1 - C2, V2, 0>, R
         <V3 + C1 + C2, V2, 0>, R
         <V3 + C1, V2, 0>, R
         <V3, V2 + C1, 0>, R
         <V3, V7 - C3, 0>, R
         <V3, V7 + C3, 0>, R
         <V3, V0 - C1, 0>, R
         <V3 + C1, V0, 0>, R
         <V3 + C1 + C2, V0, 0>, R
         <V1 - V4 - C1 - C2, V0, 0>, R
         <V1 - V4 - C1, V0, 0>, R
         <V1 - V4, V0 - C1, 0>, R
         <V1 - V4, V0 - C1 - C2 - .2, 0>, R
      } //sphere_sweep
      #declare MOP_CharacterWidth [MOP_CharacterIndex_s_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_s_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_s_] = object {
         #local V8 = StandardInvisibleOffset;
         #local V9 = V1 - V4 - .014;
         union {
            cylinder {<V3 + V8, .16, 0> <V3 + V8, .5, 0>, R}
            cylinder {<V9 - V8, .16, 0> <V9 - V8, .555, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_t_] = object {
      #local V0 = Height_Lower;
      #local V1 = .18; //Left width
      #local V2 = .53; //Right width
      #local V4 = .56; //Bottom width
      #local V5 = .86; //Stem height
      #local V6 = .16; //Hook height extension
      #local C1 = .08;
      #local C2 = .16;
      union {
         intersection {
            sphere_sweep {
               b_spline
               11
               <0, V5 + 2, 0>, R
               <0, V5, 0>, R
               <0, C1 + C2, 0>, R
               <0, C1, 0>, R
               <C1, 0, 0>, R
               <C1 + C2, 0, 0>, R
               <V4 - C1 - C2, 0, 0>, R
               <V4 - C1, 0, 0>, R
               <V4, C1, 0>, R
               <V4, C1 + C2, 0>, R
               <V4, C1 + C2 + V6, 0>, R
            } //sphere_sweep
            plane {y, V5}
         } //intersection
         sphere {<0, V5, 0>, R}
         ArbitraryHorizontalBar (-V1, V2, V0, R)
         RightAngleCornerFiller (QUADRANT1, <0, V0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, <0, V0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <0, V0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, V0, 0>, CornerRadius)
      } //union
      translate V1 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_t_] = V1 + V4;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_t_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_t_] = object {
         #local V7 = StandardInvisibleOffset;
         #local V8 = V2 + V1;
         cylinder {<V8 - V7, .23, 0> <V8 - V7, V0, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_u_] = object {
      #local V0 = Height_Lower;
      MOP_Character [MOP_CharacterIndex_n_]
      rotate 180 * z
      translate <MOP_CharacterWidth [MOP_CharacterIndex_n_], V0, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_u_] = MOP_CharacterWidth [MOP_CharacterIndex_n_];
   } //object

   #declare MOP_Character [MOP_CharacterIndex_v_] = object {
      #local V0 = Height_Lower;
      #local V_A0 = 60;
      union {
         #local V1 = 2 * ComputeCornerLength (180 + V_A0, 0, R, CornerRadius); //Width of flat part
         #local V_L0 = V0 / sin (radians (V_A0));
         #local V2 = V_L0 * cos (radians (V_A0));
         #local V_P0 = <V2, 0, 0>;
         #local V_P1 = V_P0 + <V1, 0, 0>;
         #local V_P2 = <V_P1.x + V2, V0, 0>;
         sphere {<0, V0, 0>, R}
         sphere {V_P0, R}
         sphere {V_P1, R}
         sphere {V_P2, R}
         cylinder {<0, V0, 0> V_P0, R}
         cylinder {V_P0 V_P1, R}
         cylinder {V_P1 V_P2, R}
         ArbitraryAngleCornerFiller (V_P0, 180 - V_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (V_P1, 180, V_A0, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_v_] = V_P2.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_w_] = object {
      #local V0 = Height_Lower;
      #local W_A0 = 23;
      union {
         #local W1 = 2 * ComputeCornerLength (90 + W_A0, 0, R, CornerRadius); //Width of flat part
         #local W_L0 = V0 / sin (radians (90 - W_A0));
         #local W2 = W_L0 * cos (radians (90 - W_A0));
         #local W_P0 = <0, V0, 0>;
         #local W_P1 = <W2, 0, 0>;
         #local W_P2 = W_P1 + <W1, 0, 0>;
         #local W_P3 = <W_P2.x + W2, V0, 0>;
         #local W_P4 = W_P3 + <W1, 0, 0>;
         #local W_P5 = <W_P4.x + W2, 0, 0>;
         #local W_P6 = W_P5 + <W1, 0, 0>;
         #local W_P7 = <W_P6.x + W2, V0, 0>;
         sphere {W_P0, R}
         sphere {W_P1, R}
         sphere {W_P2, R}
         sphere {W_P3, R}
         sphere {W_P4, R}
         sphere {W_P5, R}
         sphere {W_P6, R}
         sphere {W_P7, R}
         cylinder {W_P0 W_P1, R}
         cylinder {W_P1 W_P2, R}
         cylinder {W_P2 W_P3, R}
         cylinder {W_P3 W_P4, R}
         cylinder {W_P4 W_P5, R}
         cylinder {W_P5 W_P6, R}
         cylinder {W_P6 W_P7, R}
         ArbitraryAngleCornerFiller (W_P1, 90 + W_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P2, 90 - W_A0, 180, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P3, 270 - W_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P4, 270 + W_A0, 180, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P5, 90 + W_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (W_P6, 90 - W_A0, 180, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_w_] = W_P7.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_x_] = object {
      #local V0 = Height_Lower;
      #local X1 = .38; //Vertical
      #local X2 = .03; //Top vertical offset
      #local X3 = .1 / R + .05; //CornerRadius multiplier
      #local X_A0 = 44;
      #local X_L0_Bottom = X1 / sin (radians (X_A0));
      #local X_L0_Top = (V0 - (X1 - X2)) / sin (radians (X_A0));
      #local X_P0 = <X_L0_Bottom * cos (radians (X_A0)), X_L0_Bottom * sin (radians (X_A0)), 0>;
      #local X_P4 = X_P0 - <0, X2, 0>;
      #local X_P1 = <X_P0.x * 2, 0, 0>;
      #local X_P2 = <X_P4.x - X_L0_Top * cos (radians (X_A0)), V0, 0>;
      #local X_P3 = <X_P4.x + X_L0_Top * cos (radians (X_A0)), V0, 0>;
      #local X_P5 = XPoint (<0, 0, 0>, X_A0, X_P2, -X_A0)
      #local X_P6 = XPoint (X_P1, 180 - X_A0, X_P3, X_A0)
      union {
         sphere {<0, 0, 0>, R} //Bottom left
         intersection {
            cylinder {<0, 0, 0> X_P0, R}
            plane {y, 0 rotate -X_A0 * z translate X_P4}
         } //intersection
         sphere {X_P1, R} //Bottom right
         intersection {
            cylinder {X_P1 X_P0, R}
            plane {y, 0 rotate X_A0 * z translate X_P4}
         } //intersection
         sphere {X_P2, R} //Top left
         intersection {
            cylinder {X_P2 X_P4, R}
            plane {y, 0 inverse rotate X_A0 * z translate X_P0}
         } //intersection
         sphere {X_P3, R} //Top right
         intersection {
            cylinder {X_P3 X_P4, R}
            plane {y, 0 inverse rotate -X_A0 * z translate X_P0}
         } //intersection
         #local TCornerRadius = CornerRadius * X3;
         ArbitraryAngleCornerFiller (X_P0, 180 + X_A0, -X_A0, R, TCornerRadius) //Bottom
         ArbitraryAngleCornerFiller (X_P4, 180 - X_A0, X_A0, R, TCornerRadius) //Top
         ArbitraryAngleCornerFiller (X_P5, 180 - X_A0, 180 + X_A0, R, TCornerRadius) //Left
         ArbitraryAngleCornerFiller (X_P6, X_A0, -X_A0, R, TCornerRadius) //Right
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_x_] = X_P1.x;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_x_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_x_] = object {
         #local X4 = StandardInvisibleOffset;
         union {
            cylinder {<X_P2.x + X4, 0, 0> <X_P2.x + X4, Height_Lower, 0>, R}
            cylinder {<X_P3.x - X4, 0, 0> <X_P3.x - X4, Height_Lower, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_y_] = object {
      #local V0 = Height_Lower;
      #local A0 = 59; //Left side
      #local A1 = 62; //Right side
      #local V1 = sin (radians (90 - A0)) * V0 / sin (radians (A0));
      #local V2 = sin (radians (90 - A1)) * V0 / sin (radians (A1));
      #local V3 = .2; //Corner radius
      #local V4 = -.28; //Descender distance (from "g")
      #local P0 = <-V1, V0, 0>;
      #local P1 = <V2, V0, 0>;
      #local P2 = <V3 * cos (radians (A1 - 90)), V3 * sin (radians (A1 - 90)), 0>;
      #local P3 = <0, -V3, 0>;
      #local V5 = P2.y + V4 - P3.y;
      #local V6 = .09; //Extra bottom width
      #local P4 = <-sin (radians (90 - A1)) * abs (V5) / sin (radians (A1)), V5, 0>;
      #local P5 = P3 - <V6, 0, 0>;
      #local yCorner = object {
         union {
            ArbitraryRoundCorner (V3, R, 90 - A1, 0, yes)
            sphere {P2, R}
            sphere {P3, R}
            sphere {P5, R}
            cylinder {P5 P3, R}
         } //union
      } //object
      union {
         sphere {<0, 0, 0>, R}
         sphere {P0, R}
         sphere {P1, R}
         cylinder {<0, 0, 0> P0, R}
         cylinder {P4 P1, R}
         object {yCorner translate P4 - P2}
         #local TCornerRadius = CornerRadius * 3.5;
         ArbitraryAngleCornerFiller (<0, 0, 0>, 180 - A0, A1, R, CornerRadius)
         ArbitraryAngleCornerFiller (<0, 0, 0>, 180 - A0, 180 + A1, R, TCornerRadius)
      } //union
      translate V1 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_y_] = V1 + V2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_z_] = object {
      #local V0 = Height_Lower;
      #local Z1 = .81; //Width
      #local Z2 = .03; //Shorten top left
      #local Z3 = .02; //Shorten top right
      #local Z_A0 = degrees (atan (V0 / (Z1 - Z3)));
      #local Z_P0 = <Z1, 0, 0>;
      #local Z_P1 = <0, 0, 0>;
      #local Z_P2 = <Z1 - Z3, V0, 0>;
      #local Z_P3 = <Z2, V0, 0>;
      union {
         ArbitraryHorizontalBar (0, Z1, 0, R) //Bottom bar
         ArbitraryHorizontalBar (Z2, Z1 - Z3, V0, R) //Top bar
         cylinder {Z_P1 Z_P2, R}
         ArbitraryAngleCornerFiller (Z_P1, Z_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (Z_P2, 180 + Z_A0, 180, R, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_z_] = Z1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_z_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_z_] = object {
         #local Z4 = StandardInvisibleOffset;
         union {
            cylinder {<Z2 + Z4, 0, 0> <Z2 + Z4, V0, 0>, R}
            cylinder {<Z1 - Z3 - Z4, 0, 0> <Z1 - Z3 - Z4, V0, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_0_] = object {
      #local V1 = .13;
      #local V2 = 1.16; //Width
      #local V3 = .18;
      #union {
         ArbitraryClosedCircle_SS (V2, 1, V1, V3, R)
         object {
            #local PERIOD1 = R * 1 + .06; //Width
            #local PERIOD2 = PERIOD1 * .8; //Height
            #local PERIODRadius = R * .3;
            ArbitraryDot (PERIOD1, PERIOD2, PERIODRadius, R)
            translate <V2 / 2 - (PERIOD1 + PERIODRadius) / 2, .5 - (PERIOD2 + PERIODRadius) / 2, 0>
         } //object
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_0_] = V2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_1_] = object {
      #local A0 = 38.5;
      #local L0 = .53;
      union {
         #local V1 = CornerRadius + ComputeCornerLength (0, 180 + A0, R, CornerRadius); //Width of flat part
         #local P0 = <-V1, 1, 0>;
         #local P1 = P0 + <L0 * cos (radians (180 + A0)), L0 * sin (radians (180 + A0)), 0>;
         object {VerticalBar}
         sphere {P0, R}
         sphere {P1, R}
         cylinder {P0 <0, 1, 0>, R}
         cylinder {P1 P0, R}
         ArbitraryAngleCornerFiller (P0, 180 + A0, 0, R, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <0, 1, 0>, CornerRadius)
      } //union
      translate abs (P1.x) * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_1_] = abs (P1.x);
   } //object

   #declare MOP_Character [MOP_CharacterIndex_2_] = object {
      #local V1 = .1;
      #local V2 = .01; //Offset top
      #local V3 = .12;
      #local V4 = .5; //Controls length of top vertical
      #local V5 = 1.14; //Width
      #local L0 = .36;
      #local L1 = 1.12; //Determines width of top portion
      #local A0 = 5;
      #local P0 = <0, L0, 0>;
      #local P1 = P0 + <L1 * cos (radians (A0)), L1 * sin (radians (A0)), 0>;
      union {
         intersection {
            sphere_sweep {
               b_spline
               20
               <0, -1, 0>, R
               <0, 0, 0>, R
               <P0.x, P0.y - V1 - V3, 0>, R
               <P0.x, P0.y - V1, 0>, R
               P0 + <V1 * cos (radians (A0)), V1 * sin (radians (A0)), 0>, R
               P0 + <(V1 + V3) * cos (radians (A0)), (V1 + V3) * sin (radians (A0)), 0>, R
               P1 - <(V1 + V3) * cos (radians (A0)), (V1 + V3) * sin (radians (A0)), 0>, R
               P1 - <V1 * cos (radians (A0)), V1 * sin (radians (A0)), 0>, R
               P1 + <0, V1, 0>, R
               P1 + <0, V1 + V3, 0>, R
               <P1.x, 1 - V1 - V3, 0>, R
               <P1.x, 1 - V1, 0>, R
               <P1.x - V1, 1, 0>, R
               <P1.x - V1 - V3, 1, 0>, R
               <V2 + V1 + V3, 1, 0>, R
               <V2 + V1, 1, 0>, R
               <V2, 1 - V1, 0>, R
               <V2, 1 - V1 - V3, 0>, R
               <V2, 1 - V1 - V3 - .01, 0>, R
               <V2, 1 - V1 - V3 - .01 - V4, 0>, R
            } //sphere_sweep
            plane {y, 0 inverse}
         } //intersection
         ArbitraryHorizontalBar (0, V5, 0, R)
         RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_2_] = V5;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_2_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_2_] = object {
         #local V6 = StandardInvisibleOffset;
         union {
            cylinder {<V2 + V6, .1, 0> <V2 + V6, .7, 0>, R}
            cylinder {<P1.x - V6, 0, 0> <P1.x - V6, .73, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_3_] = object {
      #local V1 = .1;
      #local V1B = .09;
      #local V2 = 1.12; //Top width
      #local V3 = .2;
      #local V3B = .17;
      #local V4 = .51; //Vertical
      #local V5 = V2 + .02; //Bottom width
      #local V6 = .01; //Top offset
      #local V7 = -.2; //Controls length of middle bar
      union {
         sphere_sweep { //Top
            b_spline
            15
            <V6, 1 - V1B - V3B - .001, 0>, R
            <V6, 1 - V1B - V3B, 0>, R
            <V6, 1 - V1B, 0>, R
            <V6 + V1, 1, 0>, R
            <V6 + V1 + V3, 1, 0>, R
            <V2 - V1 - V3, 1, 0>, R
            <V2 - V1, 1, 0>, R
            <V2, 1 - V1, 0>, R
            <V2, 1 - V1 - V3, 0>, R
            <V2, V4 + V1 + V3, 0>, R
            <V2, V4 + V1, 0>, R
            <V2 - V1, V4, 0>, R
            <V2 - V1 - V3, V4, 0>, R
            <V5 / 2, V4, 0>, R
            <V7, V4, 0>, R
         } //sphere_sweep
         sphere_sweep { //Bottom
            b_spline
            15
            <0, V1B + V3B + .001, 0>, R
            <0, V1B + V3B, 0>, R
            <0, V1B, 0>, R
            <V1, 0, 0>, R
            <V1 + V3, 0, 0>, R
            <V5 - V1 - V3, 0, 0>, R
            <V5 - V1, 0, 0>, R
            <V5, V1, 0>, R
            <V5, V1 + V3, 0>, R
            <V5, V4 - V1 - V3, 0>, R
            <V5, V4 - V1, 0>, R
            <V5 - V1, V4, 0>, R
            <V5 - V1 - V3, V4, 0>, R
            <V5 / 2, V4, 0>, R
            <V7, V4, 0>, R
         } //sphere_sweep
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_3_] = V5;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_3_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_3_] = object {
         #local V8 = StandardInvisibleOffset;
         cylinder {<V6 + V8, .22, 0> <V6 + V8, .77, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_4_] = object {
      #local V2 = 1.2; //Width of lower bar
      #local A0 = 36;
      #local L0 = 1.1;
      union {
         #local V1 = CornerRadius + ComputeCornerLength (180, 270 + A0, R, CornerRadius); //Width of flat part
         #local P0 = <-V1, 1, 0>;
         #local P1 = P0 - <L0 * cos (radians (A0)), L0 * sin (radians (A0)), 0>;
         #local P2 = P1 - <0, V1, 0>;
         #local P3 = P2 + <V2, 0, 0>;
         #local P4 = <0, P2.y, 0>;
         object {VerticalBar}
         sphere {P0, R}
         sphere {P1, R}
         ArbitraryHorizontalBar (P2.x, P3.x, P2.y, R)
         cylinder {P0 <0, 1, 0>, R}
         cylinder {P1 P0, R}
         cylinder {P2 P1, R}
         #local TCornerRadius = CornerRadius * 1.5;
         ArbitraryAngleCornerFiller (P0, 0, 180 + A0, R, TCornerRadius)
         ArbitraryAngleCornerFiller (P1, 270, A0, R, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <0, 1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, P2, CornerRadius)
         RightAngleCornerFiller (QUADRANT1, P4, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, P4, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, P4, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, P4, CornerRadius)
      } //union
      translate -P1.x * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_4_] = V2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_5_] = object {
      #local V1  = .12;
      #local V1B  = .11;
      #local V2  = .22; //Corner radius
      #local V3  = .2;
      #local V3B  = .15;
      #local V4  = .645; //Vertical
      #local V5  = 1.14; //Width
      #local V6  = .02; //Top left offset
      #local V7  = V5 - .05; //Top right offset
      #local V9  = .11; //Y component of corner
      #local V10 = V4 - V9; //Vertical offset
      #local A0 = degrees (asin ((V2 - V9) / V2));
      #local V11 = sqrt (V2 * V2 - (V2 - V9) * (V2 - V9));
      union {
         ArbitraryHorizontalBar (V6, V7, 1, R)
         sphere {<V6, V10, 0>, R}
         cylinder {<V6, V10, 0> <V6, 1, 0>, R}
         #local DigitCorner = object {
            #local DigitCornerRadius = V2;
            intersection {
               torus {DigitCornerRadius, R sturm rotate 90 * x}
               plane {x, 0}
               plane {y, 0 inverse rotate -A0 * z}
            } //intersection
         } //object
         object {DigitCorner translate <V6 + V11, V4 - V2, 0>}
         sphere {<V6 + V11, V4, 0>, R}
         difference {
            sphere_sweep {
               b_spline
               15
               <0, V1B + V3B + .001, 0>, R
               <0, V1B + V3B, 0>, R
               <0, V1B, 0>, R
               <V1, 0, 0>, R
               <V1 + V3, 0, 0>, R
               <V5 - V1 - V3, 0, 0>, R
               <V5 - V1, 0, 0>, R
               <V5, V1, 0>, R
               <V5, V1 + V3, 0>, R
               <V5, V4 - V1 - V3, 0>, R
               <V5, V4 - V1, 0>, R
               <V5 - V1, V4, 0>, R
               <V5 - V1 - V3, V4, 0>, R
               <0, V4, 0>, R
               <-1, V4, 0>, R
            } //sphere_sweep
            box {<-1, V4 - R - .1, -R - .1> <V6 + V11, V4 + R + .1, R + .1>}
         } //difference
         RightAngleCornerFiller (QUADRANT4, <V6, 1, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_5_] = V5;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_5_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_5_] = object {
         #local V12 = StandardInvisibleOffset;
         union {
            cylinder {<V6 + V12, .23, 0> <V6 + V12, V10, 0>, R}
            cylinder {<V7 - V12, .5, 0> <V7 - V12, 1, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_7_] = object {
      #local V1 = 1.16; //Width
      #local A0 = 49;
      union {
         #local V2 = CornerRadius + ComputeCornerLength (180, 270 + A0, R, CornerRadius); //Width of flat part
         #local V3 = sin (radians (90 - A0)) * (1 - V2) / sin (radians (A0));
         ArbitraryHorizontalBar (0, V1, 1, R)
         #local P0 = <V1, 1 - V2, 0>;
         #local P1 = <P0.x - V3, 0, 0>;
         cylinder {P0 <V1, 1, 0>, R}
         sphere {P0, R}
         sphere {P1, R}
         cylinder {P1, P0, R}
         ArbitraryAngleCornerFiller (P0, 180 + A0, 90, R, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <V1, 1, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_7_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_7_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_7_] = object {
         #local V2 = StandardInvisibleOffset;
         intersection {
            cylinder {<P1.x + V2, 0, 0> <P1.x + V12, 1, 0>, R}
            plane {y, 0 inverse rotate A0 * z translate P1.x * x}
         } //intersection
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_8_] = object {
      #local V1 = .1;
      #local V2 = 1.12; //Width
      #local V3 = .2;
      #local V4 = .52; //Vertical
      #local V5 = .045; //Top offset
      sphere_sweep {
         b_spline
         35
         <V1 + V3, 0, 0>, R
         <V1, 0, 0>, R
         <0, V1, 0>, R
         <0, V1 + V3, 0>, R
         <0, V4 - V1 - V3, 0>, R
         <0, V4 - V1, 0>, R
         <V1, V4, 0>, R
         <V1 + V3, V4, 0>, R
         <V2 - V5 - V1 - V3, V4, 0>, R
         <V2 - V5 - V1, V4, 0>, R
         <V2 - V5, V4 + V1, 0>, R
         <V2 - V5, V4 + V1 + V3, 0>, R
         <V2 - V5, 1 - V1 - V3, 0>, R
         <V2 - V5, 1 - V1, 0>, R
         <V2 - V5 - V1, 1, 0>, R
         <V2 - V5 - V1 - V3, 1, 0>, R
         <V5 + V1 + V3, 1, 0>, R
         <V5 + V1, 1, 0>, R
         <V5, 1 - V1, 0>, R
         <V5, 1 - V1 - V3, 0>, R
         <V5, V4 + V1 + V3, 0>, R
         <V5, V4 + V1, 0>, R
         <V5 + V1, V4, 0>, R
         <V5 + V1 + V3, V4, 0>, R
         <V2 - V1 - V3, V4, 0>, R
         <V2 - V1, V4, 0>, R
         <V2, V4 - V1, 0>, R
         <V2, V4 - V1 - V3, 0>, R
         <V2, V1 + V3, 0>, R
         <V2, V1, 0>, R
         <V2 - V1, 0, 0>, R
         <V2 - V1 - V3, 0, 0>, R
         <V1 + V3, 0, 0>, R
         <V1, 0, 0>, R
         <0, V1, 0>, R
      } //sphere_sweep
      #declare MOP_CharacterWidth [MOP_CharacterIndex_8_] = V2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_9_] = object {
      #local V1 = .12;
      #local V1B = .12;
      #local V2 = 1.1; //Width
      #local V3 = .2;
      #local V3B = .12;
      #local V4 = .45; //Vertical
      #local V5 = .01; //Bottom offset
      sphere_sweep {
         b_spline
         26
         <V5, V1B + V3B + .001, 0>, R
         <V5, V1B + V3B, 0>, R
         <V5, V1B, 0>, R
         <V5 + V1, 0, 0>, R
         <V5 + V1 + V3, 0, 0>, R
         <V2 - V1 - V3, 0, 0>, R
         <V2 - V1, 0, 0>, R
         <V2, V1, 0>, R
         <V2, V1 + V3, 0>, R
         <V2, 1 - V1 - V3, 0>, R
         <V2, 1 - V1, 0>, R
         <V2 - V1, 1, 0>, R
         <V2 - V1 - V3, 1, 0>, R
         <V1 + V3, 1, 0>, R
         <V1, 1, 0>, R
         <0, 1 - V1, 0>, R
         <0, 1 - V1 - V3, 0>, R
         <0, V4 + V1 + V3, 0>, R
         <0, V4 + V1, 0>, R
         <V1, V4, 0>, R
         <V1 + V3, V4, 0>, R
         <V2 - V1 - V3, V4, 0>, R
         <V2 - V1, V4, 0>, R
         <V2, V4 + V1, 0>, R
         <V2, V4 + V1 + V3, 0>, R
         <V2, 1 - V1 - V3, 0>, R
      } //sphere_sweep
      #declare MOP_CharacterWidth [MOP_CharacterIndex_9_] = V2;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_9_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_9_] = object {
         #local V6 = StandardInvisibleOffset;
         cylinder {<V5 + V6, .22, 0> <V5 + V6, .7, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_6_] = object {
      object {MOP_Character [MOP_CharacterIndex_9_] translate -MOP_CharacterWidth [MOP_CharacterIndex_9_] * x rotate 180 * z translate 1 * y}
      #declare MOP_CharacterWidth [MOP_CharacterIndex_6_] = MOP_CharacterWidth [MOP_CharacterIndex_9_];
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_6_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_6_] = object {
         #local V6 = StandardInvisibleOffset;
         cylinder {<V5 + V6, .22, 0> <V5 + V6, .7, 0>, R translate -MOP_CharacterWidth [MOP_CharacterIndex_9_] * x rotate 180 * z translate 1 * y}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_PERIOD_] = object {
      #local PERIOD1 = R * 1.75; //Width
      #local PERIOD2 = PERIOD1 * .5; //Height
      #local PERIODRadius = R * .3;
      ArbitraryDot (PERIOD1, PERIOD2, PERIODRadius, R)
      #declare MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_] = PERIOD1 + PERIODRadius;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_COMMA_] = object {
      #local PERIOD1 = R * 1.75; //Width
      #local PERIOD2 = PERIOD1 * .5; //Height
      #local PERIODRadius = R * .3;
      #local V1 = R * 1.1;
      #local A0 = 10;
      #local CommaTailRadius = R * 1.3;
      #local CommaTail_Top = object {
         union {
            sphere {<PERIOD1, -V1, 0>, R}
            cylinder {<PERIOD1, -V1, 0> <PERIOD1, PERIOD2 / 2, 0>, R}
         } //union
      } //object
      #local CommaTail_Bottom = object {
         union {
            intersection {
               torus {CommaTailRadius, R sturm rotate 90 * x}
               plane {x, 0 rotate A0 * z inverse}
               plane {y, 0}
            } //intersection
            sphere {<CommaTailRadius * cos (radians (270 + A0)), CommaTailRadius * sin (radians (270 + A0)), 0>, R}
         } //union
      } //object
      #local CommaTail = object {
         union {
            object {CommaTail_Top}
            object {CommaTail_Bottom translate <PERIOD1 - CommaTailRadius, -V1, 0>}
         } //union
      } //object
      union {
         object {MOP_Character [MOP_CharacterIndex_PERIOD_]}
         object {CommaTail translate PERIODRadius * x}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_COMMA_] = MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_];
   } //object

   #declare MOP_Character [MOP_CharacterIndex_COLON_] = object {
      #local PERIOD1 = R * 1.75; //Width
      #local PERIOD2 = PERIOD1 * .5; //Height
      #local PERIODRadius = R * .3;
      #local V1 = .6;
      union {
         object {MOP_Character [MOP_CharacterIndex_PERIOD_]}
         object {MOP_Character [MOP_CharacterIndex_PERIOD_] translate V1 * y}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_COLON_] = MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_];
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_COLON_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_COLON_] = object {
         union {
            cylinder {<0, 0, 0> <0, V1, 0>, R}
            cylinder {<PERIOD1 + PERIODRadius, 0, 0> <PERIOD1 + PERIODRadius, V1, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_SEMICOLON_] = object {
      #local PERIOD1 = R * 1.75; //Width
      #local PERIOD2 = PERIOD1 * .5; //Height
      #local PERIODRadius = R * .3;
      #local V1 = .6;
      union {
         object {MOP_Character [MOP_CharacterIndex_COMMA_]}
         object {MOP_Character [MOP_CharacterIndex_PERIOD_] translate V1 * y}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_SEMICOLON_] = MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_];
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_SEMICOLON_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_SEMICOLON_] = object {
         union {
            cylinder {<0, 0, 0> <0, V1, 0>, R}
            cylinder {<PERIOD1 + PERIODRadius, 0, 0> <PERIOD1 + PERIODRadius, V1, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_APOSTROPHE_] = object {
      #local PERIOD1 = R * 1.75; //Width
      #local PERIOD2 = PERIOD1 * .5; //Height
      #local PERIODRadius = R * .3;
      MOP_Character [MOP_CharacterIndex_COMMA_]
      translate (1 - PERIOD2 - PERIODRadius) * y
      #declare MOP_CharacterWidth [MOP_CharacterIndex_APOSTROPHE_] = MOP_CharacterWidth [MOP_CharacterIndex_COMMA_];
   } //object

   #if (MOP_UseFrenchQuoteMarks)

      #declare MOP_Character [MOP_CharacterIndex_QUOTE_Left_] = object { //French quote mark
         #local V1 = .225;
         #local V2 = .435; //Vertical, match the "G"
         #local V3 = R * 3 + .05; //Spacing
         #local A0 = 50;
         #local L0 = V1 / sin (radians (A0));
         #local P0 = <L0 * cos (radians (A0)), L0 * sin (radians (A0)), 0>;
         #local Single = object {
            union {
               sphere {<0, P0.y, 0>, R}
               sphere {<P0.x, P0.y * 2, 0>, R}
               sphere {<P0.x, 0, 0>, R}
               cylinder {<0, P0.y, 0> <P0.x, P0.y * 2, 0>, R}
               cylinder {<0, P0.y, 0> <P0.x, 0, 0>, R}
               ArbitraryAngleCornerFiller (<0, P0.y, 0>, A0, -A0, R, CornerRadius)
            } //union
         } //object
         union {
            object {Single}
            object {Single translate V3 * x}
         } //union
         translate (V2 - P0.y) * y
         #declare MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Left_] = V3 + P0.x;
         #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_QUOTE_Left_] = yes;
         #declare MOP_InvisibleComponent [MOP_CharacterIndex_QUOTE_Left_] = object {
            #local V4 = StandardInvisibleOffset;
            intersection {
               cylinder {<P0.x - X4, 0, 0> <P0.x - X4, P0.y * 2, 0>, R}
               plane {y, 0 rotate A0 * z translate P0.y * y}
               plane {y, 0 inverse rotate -A0 * z translate P0.y * y}
            } //intersection
            translate <V3, V2 - P0.y, 0>
         } //object
      } //object

      #declare MOP_Character [MOP_CharacterIndex_QUOTE_Right_] = object {
         MOP_Character [MOP_CharacterIndex_QUOTE_Left_]
         rotate 180 * y
         translate MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Left_] * x
         #declare MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Right_] = MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Left_];
         #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_QUOTE_Right_] = yes;
         #declare MOP_InvisibleComponent [MOP_CharacterIndex_QUOTE_Right_] = object {
            MOP_InvisibleComponent [MOP_CharacterIndex_QUOTE_Left_]
            rotate 180 * y
            translate MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Left_] * x
         } //object
      } //object

   #else

      #declare MOP_Character [MOP_CharacterIndex_QUOTE_Left_] = object { //English quote mark
         #local PERIOD1 = R * 1.75; //Width
         #local PERIOD2 = PERIOD1 * .5; //Height
         #local PERIODRadius = R * .3;
         #local V1 = .035;
         #local V2 = R * sin (radians (270 + 30)) - R * 1.1; //Y offset
         union {
            object {MOP_Character [MOP_CharacterIndex_COMMA_] translate (-PERIOD2 - PERIODRadius) * y rotate 180 * z translate <MOP_CharacterWidth [MOP_CharacterIndex_COMMA_], V2, 0>}
            object {MOP_Character [MOP_CharacterIndex_COMMA_] translate (-PERIOD2 - PERIODRadius) * y rotate 180 * z translate <MOP_CharacterWidth [MOP_CharacterIndex_COMMA_] * 2 + R * 2 + V1, V2, 0>}
         } //union
         translate (1 - PERIOD2 - PERIODRadius) * y
         #declare MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Left_] = MOP_CharacterWidth [MOP_CharacterIndex_COMMA_] * 2 + R * 2 + V1;
         #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_QUOTE_Left_] = no;
      } //object

      #declare MOP_Character [MOP_CharacterIndex_QUOTE_Right_] = object {
         #local V1 = .035;
         union {
            object {MOP_Character [MOP_CharacterIndex_APOSTROPHE_]}
            object {MOP_Character [MOP_CharacterIndex_APOSTROPHE_] translate (MOP_CharacterWidth [MOP_CharacterIndex_COMMA_] + R * 2 + V1) * x}
         } //union
         #declare MOP_CharacterWidth [MOP_CharacterIndex_QUOTE_Right_] = MOP_CharacterWidth [MOP_CharacterIndex_COMMA_] * 2 + R * 2 + V1;
         #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_QUOTE_Right_] = no;
      } //object

   #end //#if

   #declare MOP_Character [MOP_CharacterIndex_EXCLAMATION_] = object {
      #local V1 = .292;
      #local V2 = MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_] / 2;
      union {
         object {MOP_Character [MOP_CharacterIndex_PERIOD_]}
         sphere {<V2, V1, 0>, R}
         sphere {<V2, 1, 0>, R}
         cylinder {<V2, V1, 0> <V2, 1, 0>, R}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_EXCLAMATION_] = MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_];
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_EXCLAMATION_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_EXCLAMATION_] = object {
         cylinder {<V2, 0, 0> <V2, V1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_QUESTION_] = object {
      #local V1 = .06;
      #local V2 = .03;
      #local V1B = .1;
      #local V1C = .04;
      #local V3 = .12;
      #local V3B = .2;
      #local V3C = .08;
      #local V4 = -.4;
      #local V5 = .25;
      #local A0 = 12;
      #local L0 = .53;
      #local P0 = <0, .44, 0>;
      #local P1 = P0 + <L0 * sin (radians (90 - A0)), L0 * sin (radians (A0)), 0>;
      union {
         sphere_sweep {
            b_spline
            20
            <0, P0.y - V1C - V3C - V2 - .01, 0>, R
            <0, P0.y - V1C - V3C - V2, 0>, R
            <0, P0.y - V1C - V3C, 0>, R
            <0, P0.y - V1C, 0>, R
            P0 + <V1 * cos (radians (A0)), V1 * sin (radians (A0)), 0>, R
            P0 + <(V1 + V3) * cos (radians (A0)), (V1 + V3) * sin (radians (A0)), 0>, R
            P1 - <(V1 + V3) * cos (radians (A0)), (V1 + V3) * sin (radians (A0)), 0>, R
            P1 - <V1 * cos (radians (A0)), V1 * sin (radians (A0)), 0>, R
            <P1.x, P1.y + V1, 0>, R
            <P1.x, P1.y + V1 + V3, 0>, R
            <P1.x, 1 - V1B - V3B, 0>, R
            <P1.x, 1 - V1B, 0>, R
            <P1.x - V1B, 1, 0>, R
            <P1.x - V1B - V3B, 1, 0>, R
            <V4 + V1B + V3B, 1, 0>, R
            <V4 + V1B, 1, 0>, R
            <V4, 1 - V1B, 0>, R
            <V4, 1 - V1B - V3B, 0>, R
            <V4, 1 - V5, 0>, R
            <V4, 1 - V5 - .02, 0>, R
         } //sphere_sweep
         object {MOP_Character [MOP_CharacterIndex_PERIOD_] translate (-MOP_CharacterWidth [MOP_CharacterIndex_PERIOD_] / 2) * x}
      } //union
      translate -V4 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_QUESTION_] = P1.x - V4;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_QUESTION_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_QUESTION_] = object {
         #local V6 = StandardInvisibleOffset;
         union {
            cylinder {<-V4, 0, 0> <-V4, .295, 0>, R}
            cylinder {<V6, .45, 0> <V6, .73, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_SLASH_] = object {
      #local V1 = .51; //Width
      union {
         sphere {<0, 0, 0>, R}
         sphere {<V1, 1, 0>, R}
         cylinder {<0, 0, 0> <V1, 1, 0>, R}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_SLASH_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_BACKSLASH_] = object {
      #local V1 = .51; //Width
      union {
         sphere {<V1, 0, 0>, R}
         sphere {<0, 1, 0>, R}
         cylinder {<V1, 0, 0> <0, 1, 0>, R}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_BACKSLASH_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_DASH_] = object {
      #local DASH1 = .6; //Width
      #local DASH2 = .435; //Vertical, match the "G"
      ArbitraryHorizontalBar (0, DASH1, DASH2, R)
      #declare MOP_CharacterWidth [MOP_CharacterIndex_DASH_] = DASH1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_PLUS_] = object {
      #local V1 = .67; //Width
      #local V2 = .435; //Vertical, match the "G"
      union {
         #local Bar = object {ArbitraryHorizontalBar (0, V1, 0, R)}
         object {Bar translate V2 * y}
         object {Bar translate (-V1 / 2) * x rotate 90 * z translate <V1 / 2, V2, 0>}
         RightAngleCornerFiller (QUADRANT1, <V1 / 2, V2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, <V1 / 2, V2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <V1 / 2, V2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <V1 / 2, V2, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_PLUS_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_EQUALS_] = object {
      #local V1 = .67; //Width
      #local V2 = .435; //Vertical, match the "G"
      #local V3 = .16; //Spacing
      union {
         #local Bar = object {ArbitraryHorizontalBar (0, V1, 0, R)}
         object {Bar translate (V2 - V3) * y}
         object {Bar translate (V2 + V3) * y}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_EQUALS_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_EQUALS_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_EQUALS_] = object {
         #local V4 = StandardInvisibleOffset;
         union {
            cylinder {<V4, V2 - V3, 0> <V4, V2 + V3, 0>, R}
            cylinder {<V1 - V4, V2 - V3, 0> <V1 - V4, V2 + V3, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_DOLLAR_] = object {
      #local S1 = .08;
      #local S2 = .96; //Top width
      #local S3 = .13;
      #local S4 = .43; //Vertical
      #local S7 = .025; //Additional bottom width
      #local S8 = .07; //Top and bottom spacing
      #local S9 = .49; //Center bar x
      union {
         sphere_sweep {
            b_spline
            26
            <0, S8 + S1 + S3 + .1, 0>, R
            <0, S8 + S1 + S3, 0>, R
            <0, S8 + S1, 0>, R
            <S1, S8, 0>, R
            <S1 + S3, S8, 0>, R
            <S2 + S7 - S1 - S3, S8, 0>, R
            <S2 + S7 - S1, S8, 0>, R
            <S2 + S7, S8 + S1, 0>, R
            <S2 + S7, S8 + S1 + S3, 0>, R
            <S2 + S7, S8 + S4 - S1 - S3, 0>, R
            <S2 + S7, S8 + S4 - S1, 0>, R
            <S2 + S7 - S1, S8 + S4, 0>, R
            <S2 + S7 - S1 - S3, S8 + S4, 0>, R
            <S1 + S3, S8 + S4, 0>, R
            <S1, S8 + S4, 0>, R
            <0, S8 + S4 + S1, 0>, R
            <0, S8 + S4 + S1 + S3, 0>, R
            <0, 1 - S8 - S1 - S3, 0>, R
            <0, 1 - S8 - S1, 0>, R
            <S1, 1 - S8, 0>, R
            <S1 + S3, 1 - S8, 0>, R
            <S2 - S1 - S3, 1 - S8, 0>, R
            <S2 - S1, 1 - S8, 0>, R
            <S2, 1 - S8 - S1, 0>, R
            <S2, 1 - S8 - S1 - S3, 0>, R
            <S2, 1 - S8 - S1 - S3 - .001, 0>, R
         } //sphere_sweep
         sphere {<S9, -R / 2, 0>, R}
         sphere {<S9, 1 + R / 2, 0>, R}
         cylinder {<S9, -R / 2, 0> <S9, 1 + R / 2, 0>, R}
         #local CornerAssembly = object {
            union {
            RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
            RightAngleCornerFiller (QUADRANT2, <0, 0, 0>, CornerRadius)
            RightAngleCornerFiller (QUADRANT3, <0, 0, 0>, CornerRadius)
            RightAngleCornerFiller (QUADRANT4, <0, 0, 0>, CornerRadius)
            } //union
         } //object
         object {CornerAssembly translate <S9, S8, 0>}
         object {CornerAssembly translate <S9, S8 + S4, 0>}
         object {CornerAssembly translate <S9, 1 - S8, 0>}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_DOLLAR_] = S2 + S7;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_DOLLAR_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_DOLLAR_] = object {
         #local S5 = StandardInvisibleOffset;
         #local S9 = S2 + .01;
         union {
            cylinder {<S5, .27, 0> <S5, .71, 0>, R}
            cylinder {<S2 - S5, .35, 0> <S2 - S5, .75, 0>, R}
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_PARENTHESIS_Left_] = object {
      #local V1 = .1;
      #local V2 = .3; //Width
      #local V3 = .24;
      sphere_sweep {
         b_spline
         10
         <V2, 0, 0>, R
         <V1 + V3, 0, 0>, R
         <V1, 0, 0>, R
         <0, V1, 0>, R
         <0, V1 + V3, 0>, R
         <0, 1 - V1 - V3, 0>, R
         <0, 1 - V1, 0>, R
         <V1, 1, 0>, R
         <V1 + V3, 1, 0>, R
         <V2, 1, 0>, R
      } //sphere_sweep
      #declare MOP_CharacterWidth [MOP_CharacterIndex_PARENTHESIS_Left_] = V2 - .007;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_PARENTHESIS_Right_] = object {
      MOP_Character [MOP_CharacterIndex_PARENTHESIS_Left_]
      translate -MOP_CharacterWidth [MOP_CharacterIndex_PARENTHESIS_Left_] * x
      rotate 180 * y
      #declare MOP_CharacterWidth [MOP_CharacterIndex_PARENTHESIS_Right_] = MOP_CharacterWidth [MOP_CharacterIndex_PARENTHESIS_Left_];
   } //object

   #declare MOP_Character [MOP_CharacterIndex_SQUAREBRACKET_Left_] = object {
      #local V1 = .28;
      union {
         ArbitraryHorizontalBar (0, V1, 0, R)
         ArbitraryHorizontalBar (0, V1, 1, R)
         cylinder {<0, 0, 0> <0, 1, 0>, R}
         RightAngleCornerFiller (QUADRANT1, <0, 0, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <0, 1, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_SQUAREBRACKET_Left_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_SQUAREBRACKET_Right_] = object {
      MOP_Character [MOP_CharacterIndex_SQUAREBRACKET_Left_]
      translate -MOP_CharacterWidth [MOP_CharacterIndex_SQUAREBRACKET_Left_] * x
      rotate 180 * y
      #declare MOP_CharacterWidth [MOP_CharacterIndex_SQUAREBRACKET_Right_] = MOP_CharacterWidth [MOP_CharacterIndex_SQUAREBRACKET_Left_];
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ANGLEBRACKET_Left_] = object {
      #local V0 = .67; //Length
      #local V3 = .435; //Vertical, match the "G"
      #local V_A0 = 66;
      union {
         #local V1 = 2 * ComputeCornerLength (180 + V_A0, 0, R, CornerRadius); //Width of flat part
         #local V_L0 = V0 / sin (radians (V_A0));
         #local V2 = V_L0 * cos (radians (V_A0));
         #local V_P0 = <V2, 0, 0>;
         #local V_P1 = V_P0 + <V1, 0, 0>;
         #local V_P2 = <V_P1.x + V2, V0, 0>;
         #local V4 = (V_P0.x + V_P1.x) / 2;
         sphere {<0, V0, 0>, R}
         sphere {V_P0, R}
         sphere {V_P1, R}
         sphere {V_P2, R}
         cylinder {<0, V0, 0> V_P0, R}
         cylinder {V_P0 V_P1, R}
         cylinder {V_P1 V_P2, R}
         ArbitraryAngleCornerFiller (V_P0, 180 - V_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (V_P1, 180, V_A0, R, CornerRadius)
      } //union
      translate -V0 * y
      rotate -90 * z
      translate <V0, V_P2.x + V3 - V4, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ANGLEBRACKET_Left_] = V0;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_ANGLEBRACKET_Left_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_ANGLEBRACKET_Left_] = object {
         #local V5 = StandardInvisibleOffset;
         intersection {
            cylinder {<0, V0 - V5, 0> <V_P2.x, V0 - V5, 0>, R}
            plane {x, 0 inverse rotate (90 - V_A0) * z translate V_P0}
            plane {y, 0 inverse rotate V_A0 * z translate V_P1}
         } //intersection
         translate -V0 * y
         rotate -90 * z
         translate <V0, V_P2.x + V3 - V4, 0>
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ANGLEBRACKET_Right_] = object {
      MOP_Character [MOP_CharacterIndex_ANGLEBRACKET_Left_]
      translate -MOP_CharacterWidth [MOP_CharacterIndex_ANGLEBRACKET_Left_] * x
      rotate 180 * y
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ANGLEBRACKET_Right_] = MOP_CharacterWidth [MOP_CharacterIndex_ANGLEBRACKET_Left_];
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_ANGLEBRACKET_Right_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_ANGLEBRACKET_Right_] = object {
         MOP_InvisibleComponent [MOP_CharacterIndex_ANGLEBRACKET_Left_]
         translate -MOP_CharacterWidth [MOP_CharacterIndex_ANGLEBRACKET_Left_] * x
         rotate 180 * y
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_PERCENT_] = object {
      #local V1 = .07;
      #local V2 = .7; //Width of circle
      #local V3 = .12;
      #local V4 = .62; //Height of circle
      #local V5 = .34; //Width of slash
      #local V6 = .75;
      union {
         #local Circle = object {ArbitraryClosedCircle_SS (V2, V4, V1, V3, R)}
         #local Slash = object {
            union {
               sphere {<0, 0, 0>, R}
               sphere {<V5, 1, 0>, R}
               cylinder {<0, 0, 0> <V5, 1, 0>, R}
            } //union
         } //object
         object {Circle translate (1 - V4) * y}
         object {Circle translate (V6 + V5 + V6 - V2) * x}
         object {Slash translate V6 * x}
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_PERCENT_] = V6 + V5 + V6;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_NUMBER_] = object {
      #local A0 = 82.5;
      #local L0 = 1 / sin (radians (A0));
      #local V1 = .165; //Polar distance from vertical center for crossbars
      #local V2 = .5; //Distance apart for diagonal bars
      #local V3 = .09 + R; //Distance horizontal bars extend past diagonal bars
      #local P0 = <L0 / 2 * cos (radians (A0)), L0 / 2 * sin (radians (A0)), 0>;
      #local P1 = P0 - <V1 * cos (radians (A0)), V1 * sin (radians (A0)), 0>;
      #local P2 = P0 + <V1 * cos (radians (A0)), V1 * sin (radians (A0)), 0>;
      #local P3 = P1 + <V2, 0, 0>;
      #local P4 = P2 + <V2, 0, 0>;
      union {
         #local DiagonalBar = object {
            union {
               sphere {<0, 0, 0>, R}
               sphere {<L0, 0, 0>, R}
               cylinder {<0, 0, 0> <L0, 0, 0>, R}
            } //union
            rotate A0 * z
         } //object
         #local HorizontalBar = object {ArbitraryHorizontalBar (0, V3 + V2 + V3, 0, R)}
         object {DiagonalBar}
         object {DiagonalBar translate V2 * x}
         object {HorizontalBar translate P1 - <V3, 0, 0>}
         object {HorizontalBar translate P2 - <V3, 0, 0>}
         #local CornerAssembly = object {
            union {
               ArbitraryAngleCornerFiller (<0, 0, 0>, 0, A0, R, CornerRadius)
               ArbitraryAngleCornerFiller (<0, 0, 0>, 0, A0 + 180, R, CornerRadius)
               ArbitraryAngleCornerFiller (<0, 0, 0>, 180, A0, R, CornerRadius)
               ArbitraryAngleCornerFiller (<0, 0, 0>, 180, A0 + 180, R, CornerRadius)
            } //union
         } //object
         object {CornerAssembly translate P1}
         object {CornerAssembly translate P2}
         object {CornerAssembly translate P3}
         object {CornerAssembly translate P4}
      } //union
      translate (-P1.x + V3) * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_NUMBER_] = -P1.x + V3 + P4.x + V3;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ASTERISK_] = object {
      #local L0 = R + .22;
      #local V1 = L0 * sin (radians (60));
      #local CenterRadius = sin (radians (60)) * R / sin (radians (30)) - R * 1.25;
      difference {
         union {
            #local Bar = object {
               union {
                  sphere {<L0, 0, 0>, R}
                  cylinder {<0, 0, 0> <L0, 0, 0>, R}
               } //union
            } //object
            sphere {<0, 0, 0>, R}
            #for (I, 0, 5)
               object {Bar rotate (I * 60) * z}
               ArbitraryAngleCornerFiller (<0, 0, 0>, I * 60, (I + 1) * 60, R, CornerRadius)
            #end //#for
         } //union
         #local Cutout = object {
            difference {
               cylinder {<0, 0, -R - .1> <0, 0, 0>, CenterRadius + R}
               torus {CenterRadius + R, R sturm rotate 90 * x}
            } //difference
         } //object
         object {Cutout}
         object {Cutout rotate 180 * x}
         cylinder {<0, 0, -R - .1> <0, 0, R + .1>, CenterRadius}
      } //difference
      translate <L0, 1 - V1, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ASTERISK_] = L0 * 2;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_ASTERISK_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_ASTERISK_] = object {
         union {
            #for (I, 0, 5)
               cylinder {<L0, 0, 0> <L0 * cos (radians (60)), L0 * sin (radians (60)), 0>, R rotate (I * 60) * z translate <L0, 1 - V1, 0>}
            #end //#for
         } //union
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_AT_] = object {
      #local V1  = 15; //Degrees
      #local V2  = .5104; //Outer radius adjustment (for 20 degrees)
      #local V2  = .5058; //Outer radius adjustment (for 15 degrees)
      #local V3  = .4; //Inner width
      #local V4  = .5; //Inner height
      #local V5  = .09;
      #local V6  = .1;
      #local V7  = .03; //X rounding factor
      #local V8  = .015; //Y rounding factor
      #local V9  = -V3 / 2 - .02; //Center X offset
      #local V10 = -V4 / 2 - .03; //Center Y offset
      #local V11 = .12; //Vertical offset for tail
      #local V12 = 5; //Angle offset
      union {
         sphere_sweep { //Center
            b_spline
            19
            <V5 + V6, 0 - V8, 0>, R
            <V5, 0, 0>, R
            <0, V5, 0>, R
            <0 - V7, V5 + V6, 0>, R
            <0 - V7, V4 - V5 - V6, 0>, R
            <0, V4 - V5, 0>, R
            <V5, V4, 0>, R
            <V5 + V6, V4 + V8, 0>, R
            <V3 - V5 - V6, V4 + V8, 0>, R
            <V3 - V5, V4, 0>, R
            <V3, V4 - V5, 0>, R
            <V3, V4 - V5 - V6, 0>, R
            <V3, V5 + V6, 0>, R
            <V3, V5, 0>, R
            <V3 - V5, 0, 0>, R
            <V3 - V5 - V6, 0 - V8, 0>, R
            <V5 + V6, 0 - V8, 0>, R
            <V5, 0, 0>, R
            <0, V5, 0>, R
            translate <V9, V10, 0>
         } //sphere_sweep
         sphere_sweep { //Outer
            b_spline
            360 / V1 - 0 + 4
            <V3, V4 + .14, 0>, R
            <V3, V4 + .13, 0>, R
            <V3, V11, 0>, R
            <V3, V11 - .08, 0>, R
            <V3 + .12, V11 - .12, 0>, R
            <V3 + .29, V11 + .04, 0>, R
            #for (I, 0, 360 - V1 * 3, V1)
               <V2 * cos (radians (I + V12)) - V9, V2 * sin (radians (I + V12)) - V10, 0>, R
            #end //#for
            translate <V9, V10, 0>
         } //sphere_sweep
      } //union
      rotate -15 * z
      translate <.5, .5, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_AT_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_CARAT_] = object {
      #local V0 = .52;
      #local V_A0 = 64;
      union {
         #local V1 = 2 * ComputeCornerLength (180 + V_A0, 0, R, CornerRadius); //Width of flat part
         #local V_L0 = V0 / sin (radians (V_A0));
         #local V2 = V_L0 * cos (radians (V_A0));
         #local V_P0 = <V2, 0, 0>;
         #local V_P1 = V_P0 + <V1, 0, 0>;
         #local V_P2 = <V_P1.x + V2, V0, 0>;
         sphere {<0, V0, 0>, R}
         sphere {V_P0, R}
         sphere {V_P1, R}
         sphere {V_P2, R}
         cylinder {<0, V0, 0> V_P0, R}
         cylinder {V_P0 V_P1, R}
         cylinder {V_P1 V_P2, R}
         ArbitraryAngleCornerFiller (V_P0, 180 - V_A0, 0, R, CornerRadius)
         ArbitraryAngleCornerFiller (V_P1, 180, V_A0, R, CornerRadius)
      } //union
      rotate 180 * x
      translate 1 * y
      #declare MOP_CharacterWidth [MOP_CharacterIndex_CARAT_] = V_P2.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_PIPE_] = object {
      #local V1 = R * 2 + .05; //Gap
      union {
         ArbitraryVerticalBar (0, 0, .5 - V1 / 2, R)
         ArbitraryVerticalBar (0, .5 + V1 / 2, 1, R)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_PIPE_] = 0;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_PIPE_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_PIPE_] = object {
         cylinder {<0, 0, 0> <0, 1, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_UNDERSCORE_] = object {
      #local V1 = .75; //Width
      #local V2 = -.2; //Vertical
      ArbitraryHorizontalBar (0, V1, V2, R)
      #declare MOP_CharacterWidth [MOP_CharacterIndex_UNDERSCORE_] = V1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_AMPERSAND_] = object {
      #local V1 = 1.43; //Width
      #local V2 = .91; //Length of tail
      #local V3 = .05; //Adjustment factor
      #local V4 = .54; //Vertical
      #local V5 = .14; //Top left offset
      #local V6 = 1.1; //Top sphere_sweep width
      #local V7 = 1.22; //Bottom sphere_sweep width
      #local C1 = .1;
      #local C2 = .15;
      #local C1B = .18;
      #local C2B = .25;
      #local A0 = 28;
      #local L0 = 1.2 + V3;
      #local L1 = L0 - .3 + V3;
      #local L2 = .8 + V3;
      #local L3 = .7 + V3;
      #local L4 = 1.3 + V3;
      union {
         #local Tail = object {
            union {
               cylinder {<0, 0, 0> <V2, 0, 0>, R}
               sphere {<0, 0, 0>, R}
            } //union
         } //object
         #local P2 = <V1, 0, 0>; //Outside tip of tail
         #local P3 = P2 + <L0 * cos (radians (180 - A0)), L0 * sin (radians (180 - A0)), 0>; //First/top control point on center bar for bottom sphere_sweep
         #local P4 = P2 + <L1 * cos (radians (180 - A0)), L1 * sin (radians (180 - A0)), 0>; //Second control point on center bar
         #local P5 = P2 + <L2 * cos (radians (180 - A0)), L2 * sin (radians (180 - A0)), 0>; //Third control point on center bar
         #local P6 = P2 + <L3 * cos (radians (180 - A0)), L3 * sin (radians (180 - A0)), 0>; //Last/bottom control point on center bar
         #local P7 = P2 + <L4 * cos (radians (180 - A0)), L4 * sin (radians (180 - A0)), 0>; //First/top control point on center bar for top sphere_sweep
         object {Tail rotate (180 - A0) * z translate P2}
         sphere_sweep { //Bottom
            b_spline
            17
            <V7, .44 + .01, 0>, R
            <V7, .44, 0>, R
            <V7, C1B + C2B, 0>, R
            <V7, C1B, 0>, R
            <V7 - C1B, 0, 0>, R
            <V7 - C1B - C2B, 0, 0>, R
            <C1 + C2, 0, 0>, R
            <C1, 0, 0>, R
            <0, C1, 0>, R
            <0, C1 + C2, 0>, R
            <0, V4 - C1 - C2, 0>, R
            <0, V4 - C1, 0>, R
            <.1, V4, 0>, R
            P3, R
            P4, R
            P5, R
            P6, R
         } //sphere_sweep
         sphere_sweep { //Top
            b_spline
            14
            <V6, 1 - C1 - C2 - .01, 0>, R
            <V6, 1 - C1 - C2, 0>, R
            <V6, 1 - C1, 0>, R
            <V6 - C1, 1, 0>, R
            <V6 - C1 - C2, 1, 0>, R
            <V5 + C1 + C2, 1, 0>, R
            <V5 + C1, 1, 0>, R
            <V5, 1 - C1, 0>, R
            <V5, 1 - C1 - C2, 0>, R
            P7, R
            P3, R
            P4, R
            P5, R
            P6, R
         } //sphere_sweep
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_AMPERSAND_] = V1;
      #declare MOP_IncludeInvisibleComponent [MOP_CharacterIndex_AMPERSAND_] = yes;
      #declare MOP_InvisibleComponent [MOP_CharacterIndex_AMPERSAND_] = object {
         cylinder {<V6, .4, 0> <V6, 1 - C1 - C2 + .03, 0>, R}
      } //object
   } //object

   #declare MOP_Character [MOP_CharacterIndex_BULLET_Round_] = object {
      #local V1 = .435; //Vertical, match the "G"
      #local V2 = .115;
      union {
         torus {V2, R sturm rotate 90 * x}
         cylinder {<0, 0, -R> <0, 0, R>, V2}
      } //union
      translate <V2, V1, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_BULLET_Round_] = V2 * 2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_BULLET_Rectangular_] = object {
      #local V1 = .435; //Vertical, match the "G"
      #local PERIOD1 = .23; //Width
      #local PERIOD2 = PERIOD1 * .8; //Height
      #local PERIODRadius = R * .3;
      ArbitraryDot (PERIOD1, PERIOD2, PERIODRadius, R)
      translate <0, V1 - (PERIOD2 + PERIODRadius) / 2, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_BULLET_Rectangular_] = PERIOD1 + PERIODRadius;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_BULLET_Triangular_] = object {
      #local V1 = .435; //Vertical, match the "G"
      #local A0 = 25;
      #local L0 = .115 / sin (radians (A0));
      #local P0 = <L0 * cos (radians (A0)), L0 * sin (radians (A0)), 0>;
      union {
         sphere {<0, P0.y, 0>, R}
         sphere {<P0.x, P0.y * 2, 0>, R}
         sphere {<P0.x, 0, 0>, R}
         cylinder {<0, P0.y, 0> <P0.x, P0.y * 2, 0>, R}
         cylinder {<0, P0.y, 0> <P0.x, 0, 0>, R}
         cylinder {<P0.x, 0, 0> <P0.x, P0.y * 2, 0>, R}
         intersection {
            box {<0, 0, -R> <P0.x, P0.y * 2, R>}
            plane {y, 0 rotate A0 * z translate P0.y * y}
            plane {y, 0 inverse rotate -A0 * z translate P0.y * y}
         } //intersection
      } //union
      rotate 180 * y
      translate <P0.x, V1 - P0.y, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_BULLET_Triangular_] = P0.x;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_COPYRIGHT_] = object {
      #local V1 = .25; //Inner radius
      #local A1 = 45; //Bottom angle
      #local A2 = -40; //Top angle
      #local P1 = <V1 * cos (radians (A1)), V1 * sin (radians (A1)), 0>;
      #local P2 = <V1 * cos (radians (A2)), V1 * sin (radians (A2)), 0>;
      union {
         torus {.5, R sturm rotate 90 * x}
         difference {
            #local Cutout = object {
               intersection {
                  box {<0, -.5, -R - .1> <.5, .5, R + .1>}
                  plane {y, 0 rotate A1 * z}
                  plane {y, 0 inverse rotate A2 * z}
               } //intersection
            } //object
            torus {V1, R sturm rotate 90 * x}
            object {Cutout}
         } //difference
         sphere {P1, R}
         sphere {P2, R}
      } //union
      translate <.5, .5, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_COPYRIGHT_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ARROW_Left_] = object {
      #local V1 = .375; //Arrow shaft width
      #local A0 = 40;
      #local L0 = .5 / sin (radians (A0));
      #local P0 = <L0 * cos (radians (A0)), L0 * sin (radians (A0)), 0>;
      #local V2 = 1 - P0.x; //Arrow shaft length
      union {
         sphere {<0, P0.y, 0>, R}
         sphere {<P0.x, P0.y * 2, 0>, R}
         sphere {<P0.x, 0, 0>, R}
         cylinder {<0, P0.y, 0> <P0.x, P0.y * 2, 0>, R}
         cylinder {<0, P0.y, 0> <P0.x, 0, 0>, R}
         cylinder {<P0.x, 0, 0> <P0.x, P0.y * 2, 0>, R}
         intersection {
            box {<0, 0, -R> <P0.x, P0.y * 2, R>}
            plane {y, 0 rotate A0 * z translate P0.y * y}
            plane {y, 0 inverse rotate -A0 * z translate P0.y * y}
         } //intersection
         sphere {<1, P0.y - V1 / 2, 0>, R}
         sphere {<1, P0.y + V1 / 2, 0>, R}
         cylinder {<P0.x, P0.y - V1 / 2, 0> <1, P0.y - V1 / 2, 0>, R}
         cylinder {<P0.x, P0.y + V1 / 2, 0> <1, P0.y + V1 / 2, 0>, R}
         cylinder {<1, P0.y - V1 / 2, 0> <1, P0.y + V1 / 2, 0>, R}
         box {<P0.x, P0.y - V1 / 2, -R> <1, P0.y + V1 / 2, R>}
         RightAngleCornerFiller (QUADRANT1, <P0.x, P0.y + V1 / 2, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <P0.x, P0.y - V1 / 2, 0>, CornerRadius)
      } //union
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ARROW_Left_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ARROW_Right_] = object {
      MOP_Character [MOP_CharacterIndex_ARROW_Left_]
      rotate 180 * y
      translate 1 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ARROW_Right_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ARROW_Up_] = object {
      MOP_Character [MOP_CharacterIndex_ARROW_Left_]
      rotate -90 * z
      translate 1 * y
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ARROW_Up_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_ARROW_Down_] = object {
      MOP_Character [MOP_CharacterIndex_ARROW_Left_]
      rotate 90 * z
      translate 1 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_ARROW_Down_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_CROSS_] = object {
      #local V1 = .15; //Stroke width
      #local V2 = .275; //Crossbar overhang
      #local V3 = .6; //Vertical
      union {
         ArbitraryVerticalBar (0, 0, 1, R)
         ArbitraryVerticalBar (V1, 0, 1, R)
         ArbitraryVerticalBar (-V2, V3, V3 + V1, R)
         ArbitraryVerticalBar (V1 + V2, V3, V3 + V1, R)
         cylinder {<0, 0, 0> <V1, 0, 0>, R}
         cylinder {<0, 1, 0> <V1, 1, 0>, R}
         cylinder {<-V2, V3, 0> <V1 + V2, V3, 0>, R}
         cylinder {<-V2, V3 + V1, 0> <V1 + V2, V3 + V1, 0>, R}
         box {<0, 0, -R> <V1, 1, R>}
         box {<-V2, V3, -R> <V1 + V2, V3 + V1, R>}
         RightAngleCornerFiller (QUADRANT1, <V1, V3 + V1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT2, <0, V3 + V1, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT3, <0, V3, 0>, CornerRadius)
         RightAngleCornerFiller (QUADRANT4, <V1, V3, 0>, CornerRadius)
      } //union
      translate V2 * x
      #declare MOP_CharacterWidth [MOP_CharacterIndex_CROSS_] = V1 + V2 * 2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_STAR_] = object {
      #local C = 1 / (cos (radians (36)) + 1);
      #local V1 = 1 - C;
      #local V2 = V1 / sin (radians (72)) * sin (radians (18));
      #local P0 = XPoint (<0, 0>, 54, <0, C>, -72)
      #local StarPoint = object {
         union {
            sphere {<0, 0, 0>, R}
            cylinder {<-V2, -V1, 0> <0, 0, 0>, R}
            cylinder {<V2, -V1, 0> <0, 0, 0>, R}
            intersection {
               box {<-V2, -V1, -R> <V2, 0, R>}
               plane {y, 0 rotate 72 * z translate <-V2, -V1, 0>}
               plane {y, 0 rotate -72 * z translate <V2, -V1, 0>}
            } //intersection
         } //union
         translate C * y
      } //object
      union {
         #for (I, 0, 4)
            object {StarPoint rotate (I * 72) * z}
            object {
               ArbitraryAngleCornerFiller (P0, 0, 108, R, CornerRadius)
               rotate (I * 72) * z
            } //object
         #end //#for
         cylinder {<0, 0, -R> <0, 0, R>, .17}
      } //union
      translate <C * cos (radians (18)), V1, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_STAR_] = C * cos (radians (18)) * 2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_DEGREE_] = object {
      #local V1 = .15;
      torus {V1, R sturm rotate 90 * x}
      translate <V1, 1 - V1, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_DEGREE_] = V1 * 2;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_SMILEY_] = object {
      #local V1 = .02; //Eye radius
      #local V2 = .1; //Eye height
      #switch (R) //Adjust eye spacing
         #range (0, .02)
            #local V3 = .16;
         #break
         #range (.02, .06)
            #local V3 = -2.5 * R + .21;
         #break
         #range (.06, 999)
            #local V3 = .06;
         #break
      #end //#switch
      #local V4 = .08; //Eye y offset
      #local V5 = .32; //Mouth radius
      #local V6 = .3; //Mouth y offset
      #local A0 = 70;
      union {
         torus {.5, R sturm rotate 90 * x}
         #local Mouth = object {
            union {
               intersection {
                  torus {V5, R sturm rotate 90 * x}
                  plane {x, 0 inverse rotate -A0 * z}
                  plane {x, 0 rotate A0 * z}
               } //intersection
               sphere {<V5 * cos (radians (270 - A0)), V5 * sin (radians (270 - A0)), 0>, R}
               sphere {<V5 * cos (radians (270 + A0)), V5 * sin (radians (270 + A0)), 0>, R}
            } //union
            translate (V5 - V6) * y
         } //object
         object {Mouth}
         #local Eye = object {
            union {
               intersection {
                  torus {V1, R sturm rotate 90 * x}
                  plane {y, 0}
               } //intersection
               intersection {
                  torus {V1, R sturm rotate 90 * x translate V2 * y}
                  plane {y, V2 inverse}
               } //intersection
               sphere {<-V1, 0, 0>, R}
               sphere {<-V1, V2, 0>, R}
               sphere {<V1, 0, 0>, R}
               sphere {<V1, V2, 0>, R}
               cylinder {<-V1, 0, 0> <-V1, V2, 0>, R}
               cylinder {<V1, 0, 0> <V1, V2, 0>, R}
               cylinder {<0, 0, -R> <0, 0, R>, V1}
               cylinder {<0, V2, -R> <0, V2, R>, V1}
               box {<-V1, 0, -R> <V1, V2, R>}
            } //union
         } //object
         object {Eye translate <-V1 - R - V3 / 2, V4, 0>}
         object {Eye translate <V1 + R + V3 / 2, V4, 0>}
      } //union
      translate <.5, .5, 0>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_SMILEY_] = 1;
   } //object

   #declare MOP_Character [MOP_CharacterIndex_METALLICA_] = object {
      #local M_ = object {
         difference {
            intersection {
               box {<0, 0, 0> <12, 21.5, 1>}
               plane {x, 0 rotate -45.7440592 * z}
            } //intersection
            intersection {
               plane {x, 0 inverse rotate -23.89516142 * z translate <5, 5.7, 0>}
               plane {x, 0 inverse rotate 13.2 * z translate <9.6, 15.5, 0>}
               plane {x, 0 rotate -51.00900596 * z translate <11.7, 17.2, 0>}
            } //intersection
            intersection {
               plane {x, 0 inverse translate <11.7, 0, 0>}
               plane {y, 0 translate <0, 18, 0>}
            } //intersection
            intersection {
               plane {x, 0 rotate -27.23908808 * z}
               plane {x, 0 inverse rotate -57.17145821 * z translate <6.5, 15.5, 0>}
            } //intersection
            difference {
               intersection {
                  plane {x, 0 inverse rotate -23.89516142 * z translate <5, 5.7, 0>}
                  plane {x, 0 rotate -9.819300639 * z translate <9, 9, 0>}
                  plane {x, 0 rotate -54.24611275 * z translate <7.8, 7.6, 0>}
               } //intersection
               intersection {
                  plane {x, 0 rotate -28 * z translate <9, 12.5, 0>}
                  plane {x, 0 inverse rotate 13.2 * z translate <9.1, 12.5, 0>}
               } //intersection
            } //difference
            cylinder {<-10.42576807, 36.53612073, -.1>, <-10.42576807, 36.53612073, 1.1>, 27}
            box {<-.1, 10, -.1> <4.5, 14, 1.1>}
         } //difference
         bounded_by {box {<-.1, -.1, -.1> <12.2, 21.6, 1.1>}}
      } //object
      #local E_ = object {
         difference {
            box {<0, 0, 0> <3.8, 5.8, 1>}
            box {<1.7, 1.66666667, -.1> <3.9, 2.06666667, 1.1>}
            box {<1.7, 3.73333333, -.1> <3.9, 4.13333333, 1.1>}
         } //difference
      } //object
      #local T_ = object {
         difference {
            box {<0, 0, 0> <6.1, 5.8, 1>}
            box {<-.1, -.1, -.1> <1, 4.13333333, 1.1>}
            box {<2.7, -.1, -.1> <6.2, 4.13333333, 1.1>}
            intersection {
               box {<2.8, 4, -.1> <6.2, 5.9, 1.1>}
               plane {x, 0 inverse rotate -23.96248897 * z translate <4.9, 5.8, 0>}
            } //intersection
         } //difference
      } //object
      #local A1_ = object {
         difference {
            intersection {
               box {<0, 0, 0> <4.4, 5.8, 1>}
               plane {x, 0 inverse rotate -23.96248897 * z}
            } //intersection
            intersection {
               plane {x, 0 translate 2.6 * x}
               plane {x, 0 inverse rotate -23.96248897 * z translate 1.8 * x}
            } //intersection
            intersection {
               box {<1.25, 3, -.1> <2.95, 5.6, 1.1>}
               plane {x, 0 inverse rotate -23.96248897 * z translate <2.45, 3, 0>}
            } //intersection * Hole in A
         } //difference
         bounded_by {box {<-.1, -.1, -.1> <4.65, 5.9, 1.1>}}
      } //object
      #local L_ = object {
         difference {
            box {<0, 0, 0> <3.55, 5.8, 1>}
            box {<1.65, 1.9, -.1> <3.7, 5.9, 1.1>}
         } //difference
      } //object
      #local I_ = object {
         box {<0, 0, 0> <1.8, 5.8, 1>}
      } //object
      #local C_ = object {
         difference {
            cylinder {<0, 0, 0>, <0, 0, 1>, 3.05}
            cylinder {<0, 0, -.1>, <0, 0, 1.1>, 1}
            intersection {
               plane {x, 0 inverse rotate -40.60129465 * z translate <.55, .55, 0>}
               plane {x, 0 rotate -125.5376778 * z translate <.75, -.3, 0>}
            } //intersection
         } //difference
      } //object
      #local A2_ = object {
         difference {
            intersection {
               box {<-2, 0, 0> <10.5, 21.5, 1>}
               plane {x, 0 rotate 45.50702906 * z translate <-2, 21.5, 0>}
               plane {x, 0 inverse rotate 46.46880071 * z translate <10.5, 0, 0>}
            } //intersection
            intersection {
               plane {x, 0 rotate 30.46554492 * z translate <-2, 21.5, 0>}
               plane {x, 0}
            } //intersection
            intersection {
               plane {x, 0 rotate 56.30993247 * z translate <1.3, 17.5, 0>}
               plane {x, 0 inverse rotate 27.73154613 * z translate <10.5, 0, 0>}
            } //intersection
            intersection {
               plane {y, 0 translate <0, 13.2, 0>}
               plane {x, 0 rotate 23.23747611 * z translate <7.85, 0, 0>}
               plane {x, 0 inverse rotate 56.30993247 * z translate <2.5, 7.6, 0>}
               plane {x, 0 inverse rotate 9.462322208 * z translate <2.15, 9, 0>}
            } //intersection
            intersection {
               plane {y, 0 inverse translate <0, 7.66, 0>}
               plane {x, 0 inverse rotate -138.0127875 * z translate <0, 11.35, 0>}
            } //intersection
            intersection {
               plane {y, 0 inverse translate <0, 14.8, 0>}
               plane {x, 0 rotate 23.23747611 * z translate <7.85, 0, 0>}
               plane {x, 0 inverse rotate 9.462322208 * z translate <2.15, 9, 0>}
            } //intersection
         } //difference
         bounded_by {box {<-2.2, -.1, -.1> <10.3, 21.6, 1.1>}}
      } //object
      union {
         object {M_}
         object {E_  translate <11.9, 11.4, 0>}
         object {T_  translate <15.9, 11.4, 0>}
         object {A1_ translate <18.75, 11.4, 0>}
         object {L_  translate <23.395, 11.4, 0>}
         object {L_  translate <27.2, 11.4, 0>}
         object {I_  translate <31, 11.4, 0>}
         object {C_  translate <36.05, 14.45, 0>}
         object {A2_ translate <38.8, 0, 0>}
      } //union
      #local S = (1 + R * 2) / 21.5;
      scale <S, S, R * 2>
      translate <-R, -R, -R>
      #declare MOP_CharacterWidth [MOP_CharacterIndex_METALLICA_] = 49.3 * S - R * 2;
   } //object

   #declare MOP_LastFontRadius    = MOP_FontRadius;
   #declare MOP_LastQuoteMarkFlag = MOP_UseFrenchQuoteMarks;

#end //#macro CreateMOP_Characters

#macro TextToIndex (Character)

   #switch (asc (Character))
      #case  (asc (" "))            #local IndexValue = MOP_CharacterIndex_SPACE_;               #break
      #case  (asc ("\""))           #local IndexValue = MOP_CharacterIndex_QUOTE_;               #break
      #range (asc ("A"), asc ("Z")) #local IndexValue = asc (Character) - asc ("A");             #break
      #range (asc ("a"), asc ("z")) #local IndexValue = asc (Character) - asc ("a") + 26;        #break
      #range (asc ("0"), asc ("9")) #local IndexValue = asc (Character) - asc ("0") + 52;        #break
      #case  (asc ("."))            #local IndexValue = MOP_CharacterIndex_PERIOD_;              #break
      #case  (asc (","))            #local IndexValue = MOP_CharacterIndex_COMMA_;               #break
      #case  (asc (":"))            #local IndexValue = MOP_CharacterIndex_COLON_;               #break
      #case  (asc (";"))            #local IndexValue = MOP_CharacterIndex_SEMICOLON_;           #break
      #case  (asc ("'"))            #local IndexValue = MOP_CharacterIndex_APOSTROPHE_;          #break
      #case  (asc ("!"))            #local IndexValue = MOP_CharacterIndex_EXCLAMATION_;         #break
      #case  (asc ("?"))            #local IndexValue = MOP_CharacterIndex_QUESTION_;            #break
      #case  (asc ("/"))            #local IndexValue = MOP_CharacterIndex_SLASH_;               #break
      #case  (asc ("\\"))           #local IndexValue = MOP_CharacterIndex_BACKSLASH_;           #break
      #case  (asc ("-"))            #local IndexValue = MOP_CharacterIndex_DASH_;                #break
      #case  (asc ("+"))            #local IndexValue = MOP_CharacterIndex_PLUS_;                #break
      #case  (asc ("="))            #local IndexValue = MOP_CharacterIndex_EQUALS_;              #break
      #case  (asc ("$"))            #local IndexValue = MOP_CharacterIndex_DOLLAR_;              #break
      #case  (asc ("("))            #local IndexValue = MOP_CharacterIndex_PARENTHESIS_Left_;    #break
      #case  (asc (")"))            #local IndexValue = MOP_CharacterIndex_PARENTHESIS_Right_;   #break
      #case  (asc ("["))            #local IndexValue = MOP_CharacterIndex_SQUAREBRACKET_Left_;  #break
      #case  (asc ("]"))            #local IndexValue = MOP_CharacterIndex_SQUAREBRACKET_Right_; #break
      #case  (asc ("<"))            #local IndexValue = MOP_CharacterIndex_ANGLEBRACKET_Left_;   #break
      #case  (asc (">"))            #local IndexValue = MOP_CharacterIndex_ANGLEBRACKET_Right_;  #break
      #case  (asc ("%"))            #local IndexValue = MOP_CharacterIndex_PERCENT_;             #break
      #case  (asc ("#"))            #local IndexValue = MOP_CharacterIndex_NUMBER_;              #break
      #case  (asc ("*"))            #local IndexValue = MOP_CharacterIndex_ASTERISK_;            #break
      #case  (asc ("@"))            #local IndexValue = MOP_CharacterIndex_AT_;                  #break
      #case  (asc ("^"))            #local IndexValue = MOP_CharacterIndex_CARAT_;               #break
      #case  (asc ("|"))            #local IndexValue = MOP_CharacterIndex_PIPE_;                #break
      #case  (asc ("_"))            #local IndexValue = MOP_CharacterIndex_UNDERSCORE_;          #break
      #case  (asc ("&"))            #local IndexValue = MOP_CharacterIndex_AMPERSAND_;           #break
      #case  (128)                  #local IndexValue = MOP_CharacterIndex_BULLET_Round_;        #break
      #case  (129)                  #local IndexValue = MOP_CharacterIndex_BULLET_Rectangular_;  #break
      #case  (130)                  #local IndexValue = MOP_CharacterIndex_BULLET_Triangular_;   #break
      #case  (131)                  #local IndexValue = MOP_CharacterIndex_COPYRIGHT_;           #break
      #case  (132)                  #local IndexValue = MOP_CharacterIndex_ARROW_Left_;          #break
      #case  (133)                  #local IndexValue = MOP_CharacterIndex_ARROW_Right_;         #break
      #case  (134)                  #local IndexValue = MOP_CharacterIndex_ARROW_Up_;            #break
      #case  (135)                  #local IndexValue = MOP_CharacterIndex_ARROW_Down_;          #break
      #case  (136)                  #local IndexValue = MOP_CharacterIndex_CROSS_;               #break
      #case  (137)                  #local IndexValue = MOP_CharacterIndex_STAR_;                #break
      #case  (138)                  #local IndexValue = MOP_CharacterIndex_DEGREE_;              #break
      #case  (139)                  #local IndexValue = MOP_CharacterIndex_SMILEY_;              #break
      #case  (140)                  #local IndexValue = MOP_CharacterIndex_METALLICA_;           #break
      #else //Undefined character
         #local IndexValue = -1;
      #break
   #end //#switch

   IndexValue

#end //#macro TextToIndex

#macro CreateMOP_TextObject (TextLine_, MOP_Gap_, MOP_Space_, MOP_FontRadius_)

   #declare MOP_Gap          = MOP_Gap_;
   #declare MOP_Space        = MOP_Space_;
   #declare MOP_FontRadius   = MOP_FontRadius_;

   #local MOP_ApplyKerning = yes;

   #if (MOP_FontRadius <= 0)
      #error "MOPFont Message: MOP_FontRadius must be > 0."
   #end //#if

   #if (MOP_FontRadius != MOP_LastFontRadius | MOP_UseFrenchQuoteMarks != MOP_LastQuoteMarkFlag)
      CreateMOP_Characters (MOP_FontRadius)
   #end //#if

   #local TextLine = TextLine_;

   #local TextLine_ = "";

   #local Done = no;
   #local StartPosition = 1;

   #while (!Done)
      #local Done = yes;
      #for (I, StartPosition, strlen (TextLine) - 1)
         #local CurrentCharacter = substr (TextLine, I, 1);
         #if (CurrentCharacter = "{")
            #local NextCharacter = strupr (substr (TextLine, I + 1, 1));
            #if (NextCharacter < "A" | NextCharacter > "M")
               #error "MOPFont Message: Undefined escape sequence."
            #end //#if
            #local Done = no;
            #if (I >= 2)
               #local TextLine_Left = substr (TextLine, 1, I - 1);
            #else
               #local TextLine_Left = "";
            #end //#if
            #if (I <= strlen (TextLine) - 2)
               #local TextLine_Right = substr (TextLine, I + 2, strlen (TextLine) - I - 1);
            #else
               #local TextLine_Right = "";
            #end //#if
            #local NextCharacterValue = asc (NextCharacter) - asc ("A");
            #local TextLine = concat (TextLine_Left, chr (NextCharacterValue + 128), TextLine_Right);
            #local StartPosition = I + 1;
            #break
         #end //#if
      #end //#for
   #end //#while

   #for (I, 1, strlen (TextLine))
      #local CurrentCharacter = substr (TextLine, I, 1);
      #if (TextToIndex (CurrentCharacter) != -1)
         #local TextLine_ = concat (TextLine_, CurrentCharacter);
      #else
         #if (CurrentCharacter != "}")
            #debug "\nMOPFont Message: A non-supported character was skipped.\n"
         #end //#if
      #end //#if
   #end //#for

   #local TextLine = TextLine_;

   #if (TextLine = "")
      #error "MOPFont Message: No valid characters."
   #end //#if

   #while (substr (TextLine, 1, 1) = " ") //Remove leading spaces
      #if (strlen (TextLine) > 1)
         #local TextLine = substr (TextLine, 2, strlen (TextLine) - 1);
      #else
         #error "MOPFont Message: No valid characters."
      #end //#if
   #end //#while

   #while (substr (TextLine, strlen (TextLine), 1) = " ") //Remove trailing spaces
      #local TextLine = substr (TextLine, 1, strlen (TextLine) - 1);
   #end //#while

   #local LineCharacterIndex = array [strlen (TextLine)]

   #local NLineCharacters = 0;
   #local NextQuote = MOP_CharacterIndex_QUOTE_Left_;

   #for (I, 1, strlen (TextLine))
      #local CurrentLineCharacterIndex = TextToIndex (substr (TextLine, I, 1));
      #if (CurrentLineCharacterIndex != MOP_CharacterIndex_SPACE_)
         #if (CurrentLineCharacterIndex = MOP_CharacterIndex_QUOTE_)
            #switch (NextQuote)
               #case (MOP_CharacterIndex_QUOTE_Left_)
                  #local CurrentLineCharacterIndex = MOP_CharacterIndex_QUOTE_Left_;
                  #local NextQuote = MOP_CharacterIndex_QUOTE_Right_;
               #break
               #case (MOP_CharacterIndex_QUOTE_Right_)
                  #local CurrentLineCharacterIndex = MOP_CharacterIndex_QUOTE_Right_;
                  #local NextQuote = MOP_CharacterIndex_QUOTE_Left_;
               #break
            #end //#switch
         #end //#if
         #local LineCharacterIndex [NLineCharacters] = CurrentLineCharacterIndex;
         #local NLineCharacters = NLineCharacters + 1;
      #end //#if
   #end //#for

   #if (NLineCharacters = 0)
      #error "MOPFont Message: No valid characters."
   #end //#if

   #if (NLineCharacters > 1 & MOP_ApplyKerning)

      #local MaximumKerningDistance = 999;

      #local Range_Lower = -.28;
      #local Range_Upper = 1;

      #local NSteps = 600; //More steps produce more accuracy but take more time.

      #local   CharacterInUse            = array [MOP_NDefinedCharacters]
      #declare MOP_CharacterFullVertical = array [MOP_NDefinedCharacters]
      #local   Kerning                   = array [MOP_NDefinedCharacters] [MOP_NDefinedCharacters]
      #declare MOP_SideDistance_Left     = array [MOP_NDefinedCharacters] [NSteps]
      #declare MOP_SideDistance_Right    = array [MOP_NDefinedCharacters] [NSteps]
      #local   CharacterIndex_Save       = array [NLineCharacters]
      #local   CurrentX_Save             = array [NLineCharacters]

      #for (I, 0, MOP_NDefinedCharacters - 1) //Initialize kerning flags
         #local CharacterInUse [I] = no;
         #declare MOP_CharacterFullVertical [I] = yes;
         #for (J, 0, MOP_NDefinedCharacters - 1)
            #local Kerning [I] [J] = 0;
         #end //#for
      #end //#for

      #for (I, 0, NLineCharacters - 1)
         #local CharacterInUse [LineCharacterIndex [I]] = yes; //Flag for character measurement
      #end //#for

      #for (I, 0, MOP_NDefinedCharacters - 1)
         #if (CharacterInUse [I])
         #if (MOP_IncludeInvisibleComponent [I])
            #local CurrentShape = object {
               union {
                  object {MOP_Character [I]}
                  object {MOP_InvisibleComponent [I]}
               } //union
            } //object
         #else
            #local CurrentShape = object {MOP_Character [I]}
         #end //#if
            MeasureCharacter (I, object {CurrentShape translate <MOP_FontRadius, 0, -1>}, Range_Lower, Range_Upper, NSteps) //Test cannot be done at z = 0 due to how trace () works.
         #end //#if
      #end //#for

      #for (I, 1, NLineCharacters - 1)
         #local Kerning [LineCharacterIndex [I - 1]] [LineCharacterIndex [I]] = -1; //Flag for character-to-character measurement
         #if (I >= 2)
            #if (!MOP_CharacterFullVertical [LineCharacterIndex [I - 1]])
               #local Kerning [LineCharacterIndex [I - 2]] [LineCharacterIndex [I]] = -1;
            #end //#if
         #end //#if
      #end //#for

      #for (I, 0, MOP_NDefinedCharacters - 1)
         #for (J, 0, MOP_NDefinedCharacters - 1)
            #if (Kerning [I] [J] = -1) //Flagged for measurement
               #local CurrentKerningValue = MeasureCharacterToCharacter (I, J, Range_Lower, Range_Upper, NSteps)
               #if (CurrentKerningValue = -1) //Characters never touch
                  #local Kerning [I] [J] = MOP_DefaultKerningDistance;
               #else
                  #if (J = MOP_CharacterIndex_APOSTROPHE_ | J = MOP_CharacterIndex_QUOTE_Left_ | J = MOP_CharacterIndex_QUOTE_Right_)
                     #local Kerning [I] [J] = min (CurrentKerningValue, MOP_DefaultKerningDistance);
                  #else
                     #local Kerning [I] [J] = min (CurrentKerningValue, MaximumKerningDistance);
                  #end //#if
               #end //#if
               //#debug concat ("\nMOPFont Message: Kerning value for characters ", str (I, 0, 0), " and ", str (J, 0, 0), ": ", str (Kerning [I] [J], 0, 3), "\n")
            #end //#if
         #end //#for
      #end //#for

   #end //#if

   #declare MOP_TextObject = object {
      #local NextQuote = MOP_CharacterIndex_QUOTE_Left_;
      #local CurrentX = 0;
      #local MaximumX = 0;
      #local NVisibleCharacters = 0;
      #if (NLineCharacters > 1)
         union {
            #for (I, 1, strlen (TextLine))
               #local CurrentCharacterIndex = TextToIndex (substr (TextLine, I, 1));
               #if (CurrentCharacterIndex = MOP_CharacterIndex_SPACE_)
                  #local CurrentX = CurrentX + MOP_Space;
               #else
                  #if (CurrentCharacterIndex = MOP_CharacterIndex_QUOTE_)
                     #switch (NextQuote)
                        #case (MOP_CharacterIndex_QUOTE_Left_)
                           #local CurrentCharacterIndex = MOP_CharacterIndex_QUOTE_Left_;
                           #local NextQuote = MOP_CharacterIndex_QUOTE_Right_;
                        #break
                        #case (MOP_CharacterIndex_QUOTE_Right_)
                           #local CurrentCharacterIndex = MOP_CharacterIndex_QUOTE_Right_;
                           #local NextQuote = MOP_CharacterIndex_QUOTE_Left_;
                        #break
                     #end //#switch
                  #end //#if
                  #if (MOP_ApplyKerning)
                     #if (NVisibleCharacters >= 2)
                        #if (!MOP_CharacterFullVertical [CharacterIndex_Save [NVisibleCharacters - 1]])
                           #local CurrentX2 = CurrentX_Save [NVisibleCharacters - 2] + MOP_CharacterWidth [CharacterIndex_Save [NVisibleCharacters - 2]] + MOP_FontRadius * 2 + MOP_Gap;
                           #local CurrentX2 = CurrentX2 - Kerning [CharacterIndex_Save [NVisibleCharacters - 2]] [CurrentCharacterIndex];
                           #local CurrentX = max (CurrentX, CurrentX2);
                        #end //#if
                     #end //#if
                     #local CharacterIndex_Save [NVisibleCharacters] = CurrentCharacterIndex; //Contains correct quote indices
                     #local CurrentX_Save [NVisibleCharacters] = CurrentX;
                     #local NVisibleCharacters = NVisibleCharacters + 1;
                  #end //#if
                  object {MOP_Character [CurrentCharacterIndex] translate CurrentX * x}
                  #local CurrentX = CurrentX + MOP_CharacterWidth [CurrentCharacterIndex] + MOP_FontRadius * 2 + MOP_Gap;
                  #local MaximumX = max (CurrentX, MaximumX);
                  #if (MOP_ApplyKerning)
                     #if (I < strlen (TextLine))
                        #for (J, I + 1, strlen (TextLine))
                           #local NextCharacterIndex = TextToIndex (substr (TextLine, J, 1));
                           #if (NextCharacterIndex != MOP_CharacterIndex_SPACE_) //Use this one
                              #if (NextCharacterIndex = MOP_CharacterIndex_QUOTE_)
                                 #switch (NextQuote)
                                    #case (MOP_CharacterIndex_QUOTE_Left_)
                                       #local NextCharacterIndex = MOP_CharacterIndex_QUOTE_Left_;
                                    #break
                                    #case (MOP_CharacterIndex_QUOTE_Right_)
                                       #local NextCharacterIndex = MOP_CharacterIndex_QUOTE_Right_;
                                    #break
                                 #end //#switch
                              #end //#if
                              #break
                           #end //#if
                        #end //#for
                        #local CurrentX = CurrentX - Kerning [CurrentCharacterIndex] [NextCharacterIndex];
                        #local CurrentX = max (CurrentX, 0); //Allow for ".T" (for example) - the "T" would be moved to x < 0
                     #end //#if
                  #end //#if
               #end //#if
            #end //#for
         } //union
      #else
         #local CurrentCharacterIndex = TextToIndex (TextLine);
         #if (CurrentCharacterIndex = MOP_CharacterIndex_QUOTE_)
            #local CurrentCharacterIndex = NextQuote;
         #end //#if
         object {MOP_Character [CurrentCharacterIndex]}
         #local MaximumX = MOP_CharacterWidth [CurrentCharacterIndex] + MOP_FontRadius * 2 + MOP_Gap;
      #end //#if
      translate <MOP_FontRadius, MOP_FontRadius, -MOP_FontRadius> //The lower left corner/back of the text object will be at the origin.
      #local S = 1 / (1 + MOP_FontRadius * 2);
      scale <S, S, S>
   } //object

   #declare MOP_TextObjectWidth = (MaximumX - MOP_Gap) * S;

#end //#macro CreateMOP_TextObject

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* *                                                                                                 * */
/* *   INITIALIZATIONS                                                                               * */
/* *                                                                                                 * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#declare MOP_DefaultKerningDistance = .12; //Default value when characters never touch or one goes "inside" another one

#declare MOP_CharacterIndex_SPACE_               = 999;
#declare MOP_CharacterIndex_QUOTE_               = 998;
#declare MOP_CharacterIndex_A_                   = 0;
#declare MOP_CharacterIndex_B_                   = 1;
#declare MOP_CharacterIndex_C_                   = 2;
#declare MOP_CharacterIndex_D_                   = 3;
#declare MOP_CharacterIndex_E_                   = 4;
#declare MOP_CharacterIndex_F_                   = 5;
#declare MOP_CharacterIndex_G_                   = 6;
#declare MOP_CharacterIndex_H_                   = 7;
#declare MOP_CharacterIndex_I_                   = 8;
#declare MOP_CharacterIndex_J_                   = 9;
#declare MOP_CharacterIndex_K_                   = 10;
#declare MOP_CharacterIndex_L_                   = 11;
#declare MOP_CharacterIndex_M_                   = 12;
#declare MOP_CharacterIndex_N_                   = 13;
#declare MOP_CharacterIndex_O_                   = 14;
#declare MOP_CharacterIndex_P_                   = 15;
#declare MOP_CharacterIndex_Q_                   = 16;
#declare MOP_CharacterIndex_R_                   = 17;
#declare MOP_CharacterIndex_S_                   = 18;
#declare MOP_CharacterIndex_T_                   = 19;
#declare MOP_CharacterIndex_U_                   = 20;
#declare MOP_CharacterIndex_V_                   = 21;
#declare MOP_CharacterIndex_W_                   = 22;
#declare MOP_CharacterIndex_X_                   = 23;
#declare MOP_CharacterIndex_Y_                   = 24;
#declare MOP_CharacterIndex_Z_                   = 25;
#declare MOP_CharacterIndex_a_                   = 26;
#declare MOP_CharacterIndex_b_                   = 27;
#declare MOP_CharacterIndex_c_                   = 28;
#declare MOP_CharacterIndex_d_                   = 29;
#declare MOP_CharacterIndex_e_                   = 30;
#declare MOP_CharacterIndex_f_                   = 31;
#declare MOP_CharacterIndex_g_                   = 32;
#declare MOP_CharacterIndex_h_                   = 33;
#declare MOP_CharacterIndex_i_                   = 34;
#declare MOP_CharacterIndex_j_                   = 35;
#declare MOP_CharacterIndex_k_                   = 36;
#declare MOP_CharacterIndex_l_                   = 37;
#declare MOP_CharacterIndex_m_                   = 38;
#declare MOP_CharacterIndex_n_                   = 39;
#declare MOP_CharacterIndex_o_                   = 40;
#declare MOP_CharacterIndex_p_                   = 41;
#declare MOP_CharacterIndex_q_                   = 42;
#declare MOP_CharacterIndex_r_                   = 43;
#declare MOP_CharacterIndex_s_                   = 44;
#declare MOP_CharacterIndex_t_                   = 45;
#declare MOP_CharacterIndex_u_                   = 46;
#declare MOP_CharacterIndex_v_                   = 47;
#declare MOP_CharacterIndex_w_                   = 48;
#declare MOP_CharacterIndex_x_                   = 49;
#declare MOP_CharacterIndex_y_                   = 50;
#declare MOP_CharacterIndex_z_                   = 51;
#declare MOP_CharacterIndex_0_                   = 52;
#declare MOP_CharacterIndex_1_                   = 53;
#declare MOP_CharacterIndex_2_                   = 54;
#declare MOP_CharacterIndex_3_                   = 55;
#declare MOP_CharacterIndex_4_                   = 56;
#declare MOP_CharacterIndex_5_                   = 57;
#declare MOP_CharacterIndex_6_                   = 58;
#declare MOP_CharacterIndex_7_                   = 59;
#declare MOP_CharacterIndex_8_                   = 60;
#declare MOP_CharacterIndex_9_                   = 61;
#declare MOP_CharacterIndex_PERIOD_              = 62;
#declare MOP_CharacterIndex_COMMA_               = 63;
#declare MOP_CharacterIndex_COLON_               = 64;
#declare MOP_CharacterIndex_SEMICOLON_           = 65;
#declare MOP_CharacterIndex_APOSTROPHE_          = 66;
#declare MOP_CharacterIndex_QUOTE_Left_          = 67;
#declare MOP_CharacterIndex_QUOTE_Right_         = 68;
#declare MOP_CharacterIndex_EXCLAMATION_         = 69;
#declare MOP_CharacterIndex_QUESTION_            = 70;
#declare MOP_CharacterIndex_SLASH_               = 71;
#declare MOP_CharacterIndex_BACKSLASH_           = 72;
#declare MOP_CharacterIndex_DASH_                = 73;
#declare MOP_CharacterIndex_PLUS_                = 74;
#declare MOP_CharacterIndex_EQUALS_              = 75;
#declare MOP_CharacterIndex_DOLLAR_              = 76;
#declare MOP_CharacterIndex_PARENTHESIS_Left_    = 77;
#declare MOP_CharacterIndex_PARENTHESIS_Right_   = 78;
#declare MOP_CharacterIndex_SQUAREBRACKET_Left_  = 79;
#declare MOP_CharacterIndex_SQUAREBRACKET_Right_ = 80;
#declare MOP_CharacterIndex_ANGLEBRACKET_Left_   = 81;
#declare MOP_CharacterIndex_ANGLEBRACKET_Right_  = 82;
#declare MOP_CharacterIndex_PERCENT_             = 83;
#declare MOP_CharacterIndex_NUMBER_              = 84;
#declare MOP_CharacterIndex_ASTERISK_            = 85;
#declare MOP_CharacterIndex_AT_                  = 86;
#declare MOP_CharacterIndex_CARAT_               = 87;
#declare MOP_CharacterIndex_PIPE_                = 88;
#declare MOP_CharacterIndex_UNDERSCORE_          = 89;
#declare MOP_CharacterIndex_AMPERSAND_           = 90;
#declare MOP_CharacterIndex_BULLET_Round_        = 91;
#declare MOP_CharacterIndex_BULLET_Rectangular_  = 92;
#declare MOP_CharacterIndex_BULLET_Triangular_   = 93;
#declare MOP_CharacterIndex_COPYRIGHT_           = 94;
#declare MOP_CharacterIndex_ARROW_Left_          = 95;
#declare MOP_CharacterIndex_ARROW_Right_         = 96;
#declare MOP_CharacterIndex_ARROW_Up_            = 97;
#declare MOP_CharacterIndex_ARROW_Down_          = 98;
#declare MOP_CharacterIndex_CROSS_               = 99;
#declare MOP_CharacterIndex_STAR_                = 100;
#declare MOP_CharacterIndex_DEGREE_              = 101;
#declare MOP_CharacterIndex_SMILEY_              = 102;
#declare MOP_CharacterIndex_METALLICA_           = 103;

#declare MOP_NDefinedCharacters = 104;

#declare MOP_Character                 = array [MOP_NDefinedCharacters];
#declare MOP_CharacterWidth            = array [MOP_NDefinedCharacters];
#declare MOP_IncludeInvisibleComponent = array [MOP_NDefinedCharacters];
#declare MOP_InvisibleComponent        = array [MOP_NDefinedCharacters];

#ifndef (MOP_Gap)                 #declare MOP_Gap                 = .14;   #end
#ifndef (MOP_Space)               #declare MOP_Space               = .65;   #end
#ifndef (MOP_FontRadius)          #declare MOP_FontRadius          = .0625; #end
#ifndef (MOP_UseFrenchQuoteMarks) #declare MOP_UseFrenchQuoteMarks = no;    #end

CreateMOP_Characters (MOP_FontRadius)