commit 9c06394ae8c3a930f09d666e9914724a53836a7c
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sun Aug 8 16:21:16 2021 +0200

    Standarize drawing stickers of a twisty puzzle. From now on, there's no 'sticker drawing' code in the individual classes, only some constants.

diff --git a/src/main/java/org/distorted/helpers/FactorySticker.java b/src/main/java/org/distorted/helpers/FactorySticker.java
index 4e15cda6..f3bee856 100644
--- a/src/main/java/org/distorted/helpers/FactorySticker.java
+++ b/src/main/java/org/distorted/helpers/FactorySticker.java
@@ -249,8 +249,13 @@ public class FactorySticker
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC
 
-  public void drawRoundedPolygon(Canvas canvas, Paint paint, int left, int top, float[] vertices, float[] angles, float stroke, int color, float[] radii)
+  public void drawRoundedPolygon(Canvas canvas, Paint paint, int left, int top, int color, ObjectSticker sticker)
     {
+    float stroke = sticker.getStroke();
+    float[] vertices = sticker.getCoords();
+    float[] angles = sticker.getCurvature();
+    float[] radii = sticker.getRadii();
+
     stroke *= TEXTURE_HEIGHT;
 
     paint.setAntiAlias(true);
diff --git a/src/main/java/org/distorted/helpers/ObjectSticker.java b/src/main/java/org/distorted/helpers/ObjectSticker.java
new file mode 100644
index 00000000..8ca437dc
--- /dev/null
+++ b/src/main/java/org/distorted/helpers/ObjectSticker.java
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2021 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is free software: you can redistribute it and/or modify                            //
+// it under the terms of the GNU General Public License as published by                          //
+// the Free Software Foundation, either version 2 of the License, or                             //
+// (at your option) any later version.                                                           //
+//                                                                                               //
+// Magic Cube is distributed in the hope that it will be useful,                                 //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
+// GNU General Public License for more details.                                                  //
+//                                                                                               //
+// You should have received a copy of the GNU General Public License                             //
+// along with Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.helpers;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class ObjectSticker
+  {
+  private final float[] mCoords;
+  private final float[] mCurvature;
+  private final float[] mRadii;
+  private final float mStroke;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public ObjectSticker(float[] coords, float[] curvature, float[] radii, float stroke)
+    {
+    mCoords    = coords;
+    mCurvature = curvature;
+    mRadii     = radii;
+    mStroke    = stroke;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float[] getCoords()
+    {
+    return mCoords;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float[] getCurvature()
+    {
+    return mCurvature;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float[] getRadii()
+    {
+    return mRadii;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public float getStroke()
+    {
+    return mStroke;
+    }
+  }
diff --git a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
index 2fb1c1c5..d0c5442a 100644
--- a/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
+++ b/src/main/java/org/distorted/objects/TwistyBandagedAbstract.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.VertexEffect;
 import org.distorted.library.effect.VertexEffectMove;
@@ -137,8 +135,30 @@ abstract class TwistyBandagedAbstract extends TwistyObject
 
   private static final int NUM_STICKERS = mStickerDimensions.length;
 
+  private static final ObjectSticker[] mStickers;
+
   private static MeshBase[] mMeshes;
 
+  static
+    {
+    mStickers = new ObjectSticker[NUM_STICKERS];
+
+    for(int s=0; s<NUM_STICKERS; s++)
+      {
+      float X = mStickerDimensions[s][0];
+      float Y = mStickerDimensions[s][1];
+      float MAX = Math.max(X,Y);
+      X /= (2*MAX);
+      Y /= (2*MAX);
+
+      float R = 0.10f / MAX;
+      float S = 0.08f / MAX;
+      float[] coords = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
+      float[] radii = new float[] {R,R,R,R};
+      mStickers[s] = new ObjectSticker(coords,null,radii,S);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyBandagedAbstract(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -368,24 +388,16 @@ abstract class TwistyBandagedAbstract extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
+    {
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectSticker retSticker(int face)
     {
-    int numFaces = FACE_COLORS.length;
-    int stickerType = face/numFaces;
-    int color = face%numFaces;
-    float X = mStickerDimensions[stickerType][0];
-    float Y = mStickerDimensions[stickerType][1];
-    float MAX = Math.max(X,Y);
-    float R = 0.10f / MAX;
-    float S = 0.08f / MAX;
-    float[] RS = new float[] {R,R,R,R};
-    X /= (2*MAX);
-    Y /= (2*MAX);
-
-    float[] vertices = { -X,-Y, +X,-Y, +X,+Y, -X,+Y};
-
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, vertices, null, S, FACE_COLORS[color], RS);
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyCube.java b/src/main/java/org/distorted/objects/TwistyCube.java
index 90f51580..91478c68 100644
--- a/src/main/java/org/distorted/objects/TwistyCube.java
+++ b/src/main/java/org/distorted/objects/TwistyCube.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
@@ -120,8 +118,19 @@ class TwistyCube extends TwistyObject
               { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f }
           };
 
+  private static final ObjectSticker[] mStickers;
+
   private static MeshBase[] mMeshes;
 
+  static
+    {
+    final float radius = 0.10f;
+    final float stroke = 0.08f;
+    final float[] radii = {radius,radius,radius,radius};
+    mStickers = new ObjectSticker[STICKERS.length];
+    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke );
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyCube(int size, Static4D quat, DistortedTexture texture,
@@ -179,14 +188,16 @@ class TwistyCube extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    float R = 0.10f;
-    float S = 0.08f;
-    float[] RS = new float[] {R,R,R,R};
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], null, S, FACE_COLORS[face], RS);
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyDiamond.java b/src/main/java/org/distorted/objects/TwistyDiamond.java
index ff06df4b..5903a4fb 100644
--- a/src/main/java/org/distorted/objects/TwistyDiamond.java
+++ b/src/main/java/org/distorted/objects/TwistyDiamond.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -138,8 +136,19 @@ public class TwistyDiamond extends TwistyObject
              { -0.4330127f, -0.25f, 0.4330127f, -0.25f, 0.0f, 0.5f }
           };
 
+  private static final ObjectSticker[] mStickers;
+
   private static MeshBase[] mMeshes;
 
+  static
+    {
+    float radius = 0.06f;
+    float stroke = 0.07f;
+    float[] radii = new float[] {radius,radius,radius};
+    mStickers = new ObjectSticker[STICKERS.length];
+    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyDiamond(int size, Static4D quat, DistortedTexture texture,
@@ -491,14 +500,16 @@ public class TwistyDiamond extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    float R = 0.06f;
-    float S = 0.07f;
-    float[] RS = new float[] {R,R,R};
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], null, S, FACE_COLORS[face], RS);
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyDino.java b/src/main/java/org/distorted/objects/TwistyDino.java
index 01bd39a5..3cda6cb0 100644
--- a/src/main/java/org/distorted/objects/TwistyDino.java
+++ b/src/main/java/org/distorted/objects/TwistyDino.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -105,12 +103,23 @@ public abstract class TwistyDino extends TwistyObject
              {3,2,0},
           };
 
+  private static MeshBase[] mMeshes;
+
   private static final float[][] STICKERS = new float[][]
           {
              { 0.0f, -1.0f/3, 0.5f, 1.0f/6, -0.5f, 1.0f/6 }
           };
 
-  private static MeshBase[] mMeshes;
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    float radius = 0.025f;
+    float stroke = 0.050f;
+    float[] radii = new float[] {radius,radius,radius};
+    mStickers = new ObjectSticker[STICKERS.length];
+    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -213,14 +222,16 @@ public abstract class TwistyDino extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    float R = 0.025f;
-    float S = 0.05f;
-    float[] RS = new float[] {R,R,R};
+    return FACE_COLORS[face];
+    }
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], null, S, FACE_COLORS[face], RS);
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyHelicopter.java b/src/main/java/org/distorted/objects/TwistyHelicopter.java
index 20d14b1c..1f921b93 100644
--- a/src/main/java/org/distorted/objects/TwistyHelicopter.java
+++ b/src/main/java/org/distorted/objects/TwistyHelicopter.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -223,12 +221,23 @@ public class TwistyHelicopter extends TwistyObject
             { 2,0,3 }
           };
 
+  private static MeshBase[] mMeshes;
+
   private static final float[][] STICKERS = new float[][]
           {
             { -0.5f, 0.25f, 0.25f, -0.5f, 0.25f, 0.25f }
           };
 
-  private static MeshBase[] mMeshes;
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    float radius = 0.03f;
+    float stroke = 0.05f;
+    float[] radii = new float[] {radius,radius,radius};
+    mStickers = new ObjectSticker[STICKERS.length];
+    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
+    }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -375,14 +384,16 @@ public class TwistyHelicopter extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    float R = 0.03f;
-    float S = 0.05f;
-    float[] RS = new float[] {R,R,R};
+    return FACE_COLORS[face];
+    }
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], null, S, FACE_COLORS[face], RS);
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyIvy.java b/src/main/java/org/distorted/objects/TwistyIvy.java
index 568ed720..f08dc840 100644
--- a/src/main/java/org/distorted/objects/TwistyIvy.java
+++ b/src/main/java/org/distorted/objects/TwistyIvy.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.VertexEffect;
 import org.distorted.library.effect.VertexEffectMove;
@@ -107,6 +105,29 @@ public class TwistyIvy extends TwistyObject
 
   private static MeshBase mCornerMesh, mFaceMesh;
 
+  private static final int NUM_STICKERS = 2;
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[NUM_STICKERS];
+
+    float A = (+0.5f-IVY_M)*IVY_C;
+    float B = (-0.5f-IVY_M)*IVY_C;
+    float C = 0.50f-IVY_D;
+    float D = (float)(Math.PI/4);
+
+    final float[][] coords = { {A,B,A,A,B,A},{-C,C,C,-C} };
+    final float[][] angles = { { 0,0,D },{ D,D } };
+    final float[][] radii  = { { 0,0.02f,0 },{ 0.06f,0.06f } };
+    final float[] strokes = { 0.03f, 0.08f };
+
+    for(int s=0; s<NUM_STICKERS; s++)
+      {
+      mStickers[s] = new ObjectSticker(coords[s],angles[s],radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyIvy(int size, Static4D quat, DistortedTexture texture,
@@ -147,7 +168,7 @@ public class TwistyIvy extends TwistyObject
 
   int getNumStickerTypes(int numLayers)
     {
-    return 2;
+    return NUM_STICKERS;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -392,41 +413,16 @@ public class TwistyIvy extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    FactorySticker factory = FactorySticker.getInstance();
-
-    if( face<COLORS )
-      {
-      float S = 0.03f;
-      float R = 0.02f;
-      float[] RS = new float[] {0,R,0};
-
-      float ANGLE = (float)(Math.PI/4);
-
-      float A = (+0.5f-IVY_M)*IVY_C;
-      float B = (-0.5f-IVY_M)*IVY_C;
-
-      float[] vertices = new float[] { A, B, A, A, B, A };
-      float[] angles   = new float[] { 0, 0, ANGLE };
-
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, angles, S, FACE_COLORS[face%COLORS], RS);
-      }
-    else
-      {
-      float S = 0.08f;
-      float R = 0.06f;
-      float[] RS = new float[] {R,R};
-
-      float ANGLE = (float)(Math.PI/4);
-      float A = 0.50f-IVY_D;
+    return FACE_COLORS[face];
+    }
 
-      float[] vertices = new float[] { -A, A, A, -A };
-      float[] angles   = new float[] { ANGLE, ANGLE };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, angles, S, FACE_COLORS[face%COLORS], RS);
-      }
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyJing.java b/src/main/java/org/distorted/objects/TwistyJing.java
index 745c2149..47d3e852 100644
--- a/src/main/java/org/distorted/objects/TwistyJing.java
+++ b/src/main/java/org/distorted/objects/TwistyJing.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -204,6 +202,23 @@ public class TwistyJing extends TwistyObject
 
   private static MeshBase[] mMeshes;
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length];
+    final float R1 = 0.05f;
+    final float R2 = 0.10f;
+    final float R3 = 0.03f;
+    final float[][] radii  = { { R1,R1,R1,R1 },{ R3,R3,R2,R2 },{ R1,R1,R1 } };
+    final float[] strokes = { 0.06f, 0.03f, 0.05f };
+
+    for(int s=0; s<STICKERS.length; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyJing(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -370,22 +385,16 @@ public class TwistyJing extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    int stickerType = face/COLORS;
-    float R,S;
-    float[] RS;
+    return FACE_COLORS[face];
+    }
 
-    switch(stickerType)
-      {
-      case 0:  R = 0.05f; S = 0.06f; RS = new float[] {R,R,R,R}; break;
-      case 1:  R = 0.03f; S = 0.03f; RS = new float[] {R,R,R,R}; break;
-      default: R = 0.05f; S = 0.05f; RS = new float[] {R,R,R  }; break;
-      }
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], null, S, FACE_COLORS[face%COLORS], RS);
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyKilominx.java b/src/main/java/org/distorted/objects/TwistyKilominx.java
index c21df6e6..4ed25ae1 100644
--- a/src/main/java/org/distorted/objects/TwistyKilominx.java
+++ b/src/main/java/org/distorted/objects/TwistyKilominx.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.helpers.QuatHelper;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
@@ -60,12 +58,9 @@ public class TwistyKilominx extends TwistyMinx
 
   private static final float CENTER_CORR = 0.87f;
 
-  private static final float C = 1.14f; // make the 'center' sticker artificially larger, so that we paint
-                                        // over the area in the center of the face.
-
   private static final float[][] STICKERS = new float[][]
       {
-        { C*-0.36616942f, C*-0.36327124f, C*0.5f, C*-0.36327124f, C*0.23233888f, C*0.4605048f, C*-0.36616942f, C*0.26603764f },
+        { -0.36616942f, -0.36327124f, 0.5f, -0.36327124f, 0.23233888f, 0.4605048f, -0.36616942f, 0.26603764f },
         { -0.36327127f, -0.5f, 0.36327127f, -0.26393202f, 0.36327127f, 0.5f, -0.36327127f, 0.26393202f },
         { -0.3249197f, -0.39442718f, 0.3249197f, -0.39442718f, 0.3249197f, 0.5f, -0.3249197f, 0.2888544f }
       };
@@ -74,14 +69,41 @@ public class TwistyKilominx extends TwistyMinx
 
   static
     {
+    final float C = 1.14f; // make the 'center' sticker artificially larger, so that we paint
+                           // over the area in the center of the face.
+
     int[] sizes = ObjectList.KILO.getSizes();
     int variants = sizes.length;
     mNumCornerEdgeVariants = sizes[0]==3 ? variants-1 : variants;
 
+    STICKERS[0][0] *= C;
+    STICKERS[0][1] *= C;
+    STICKERS[0][2] *= C;
+    STICKERS[0][3] *= C;
+    STICKERS[0][4] *= C;
+    STICKERS[0][5] *= C;
+    STICKERS[0][6] *= C;
+    STICKERS[0][7] *= C;
+
     STICKERS[0][2] *= CENTER_CORR;
     STICKERS[0][3] *= CENTER_CORR;
     }
 
+  private static final ObjectSticker[] mStickers;
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length];
+
+    float R = 0.10f;
+    final float[][] radii = { {R,R,R,R},{R,R,R,R},{R,R,R,R} };
+    final float[] strokes = { 0.20f, 0.11f, 0.10f };
+
+    for(int s=0; s<STICKERS.length; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyKilominx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -635,37 +657,29 @@ public class TwistyKilominx extends TwistyMinx
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    int variant = face/COLORS;
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[getStickerIndex(face)];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getStickerIndex(int face)
+    {
+    int variant = face/NUM_FACES;
     int numLayers = getNumLayers();
 
-    if( variant == (numLayers-1)/2 || numLayers==3 ) // center
-      {
-      float R = 0.10f;
-      float S = 0.20f;
-      float[] RS = new float[] {R,R,R,R};
+    if( variant == (numLayers-1)/2 || numLayers==3 ) return 0;
+    if( variant==0 ) return 1;
 
-      FactorySticker factory = FactorySticker.getInstance();
-      factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], null, S, FACE_COLORS[face%NUM_FACES], RS);
-      }
-    else if( variant==0 ) // corner
-      {
-      float R = 0.10f;
-      float S = 0.11f;
-      float[] RS = new float[] {R,R,R,R};
-      FactorySticker factory = FactorySticker.getInstance();
-      factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[1], null, S, FACE_COLORS[face%COLORS], RS);
-      }
-    else  // edge
-      {
-      float R = 0.10f;
-      float S = 0.10f;
-      float[] RS = new float[] {R,R,R,R};
-      FactorySticker factory = FactorySticker.getInstance();
-      factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[2], null, S, FACE_COLORS[face%COLORS], RS);
-      }
+    return 2;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyMegaminx.java b/src/main/java/org/distorted/objects/TwistyMegaminx.java
index 9ce0393e..5235559a 100644
--- a/src/main/java/org/distorted/objects/TwistyMegaminx.java
+++ b/src/main/java/org/distorted/objects/TwistyMegaminx.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.helpers.QuatHelper;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
@@ -58,6 +56,25 @@ public class TwistyMegaminx extends TwistyMinx
         { -0.29389262f, 0.4045085f, -0.47552824f, -0.1545085f, 0.0f, -0.5f, 0.47552824f, -0.1545085f, 0.29389262f, 0.4045085f }
       };
 
+  private static final ObjectSticker[] mStickers;
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length];
+
+    final float R0 = 0.08f;
+    final float R1 = 0.12f;
+    final float R2 = 0.12f;
+    final float R3 = 0.08f;
+    final float R4 = 0.10f;
+    final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4,R4,R4} };
+    final float[] strokes = { 0.10f,0.12f,0.12f,0.08f,0.07f };
+
+    for(int s=0; s<STICKERS.length; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyMegaminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -531,32 +548,39 @@ public class TwistyMegaminx extends TwistyMinx
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    float R,S;
-    float[] RS;
-    int index,variant = face/COLORS;
+    return FACE_COLORS[face];
+    }
 
-    if( variant==0 ) { R = 0.08f; S = 0.10f; index = 0; RS = new float[] {R,R,R,R}; }
-    else
-      {
-      int numLayers = getNumLayers();
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[getStickerIndex(face)];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private int getStickerIndex(int face)
+    {
+    int variant = face/NUM_FACES;
 
-      if( variant < (numLayers+1)/2 )
+    if( variant==0 ) return 0;
+
+    int numLayers = getNumLayers();
+
+    if( variant < (numLayers+1)/2 )
+      {
+      if( numLayers==3 ) return 1;
+      else
         {
-        if( numLayers==3 ) { R = 0.12f; S = 0.12f; index = 1; RS = new float[] {R,R,R,R}; }
-        else
-          {
-          if( variant==1 ) { R = 0.12f; S = 0.12f; index = 2; RS = new float[] {R,R,R,R}; }
-          else             { R = 0.08f; S = 0.08f; index = 3; RS = new float[] {R,R,R,R}; }
-          }
+        if( variant==1 ) return 2;
+        else             return 3;
         }
-      else { R = 0.10f; S = 0.07f; index = 4; RS = new float[] {R,R,R,R,R}; }
       }
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[index], null, S, FACE_COLORS[face%COLORS], RS);
+    return 4;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyObject.java b/src/main/java/org/distorted/objects/TwistyObject.java
index c90d3f19..dd928fb3 100644
--- a/src/main/java/org/distorted/objects/TwistyObject.java
+++ b/src/main/java/org/distorted/objects/TwistyObject.java
@@ -28,6 +28,8 @@ import android.graphics.Paint;
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
 import org.distorted.helpers.FactoryCubit;
+import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.helpers.QuatHelper;
 import org.distorted.library.effect.Effect;
 import org.distorted.library.effect.MatrixEffectMove;
@@ -588,14 +590,16 @@ public abstract class TwistyObject extends DistortedNode
     paint.setColor(COLOR_BLACK);
     canvas.drawRect(0, 0, mNumTexCols*TEXTURE_HEIGHT, mNumTexRows*TEXTURE_HEIGHT, paint);
 
-    int tex = 0;
+    int face = 0;
+    FactorySticker factory = FactorySticker.getInstance();
 
     for(int row=0; row<mNumTexRows; row++)
       for(int col=0; col<mNumTexCols; col++)
         {
-        if( tex>=NUM_TEXTURES ) break;
-        createFaceTexture(canvas, paint, tex, col*TEXTURE_HEIGHT, row*TEXTURE_HEIGHT);
-        tex++;
+        if( face>=NUM_TEXTURES ) break;
+        ObjectSticker sticker = retSticker(face);
+        factory.drawRoundedPolygon(canvas, paint, col*TEXTURE_HEIGHT, row*TEXTURE_HEIGHT, getColor(face%NUM_FACES), sticker);
+        face++;
         }
 
     if( !mTexture.setTexture(bitmap) )
@@ -970,7 +974,8 @@ public abstract class TwistyObject extends DistortedNode
   abstract int getNumStickerTypes(int numLayers);
   abstract int getNumCubitFaces();
   abstract MeshBase createCubitMesh(int cubit, int numLayers);
-  abstract void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top);
+  abstract ObjectSticker retSticker(int face);
+  abstract int getColor(int face);
   abstract int getFaceColor(int cubit, int cubitface, int numLayers);
   abstract float returnMultiplier();
   abstract float[][] getCuts(int numLayers);
diff --git a/src/main/java/org/distorted/objects/TwistyPyraminx.java b/src/main/java/org/distorted/objects/TwistyPyraminx.java
index c67a1cc1..9c7f49a1 100644
--- a/src/main/java/org/distorted/objects/TwistyPyraminx.java
+++ b/src/main/java/org/distorted/objects/TwistyPyraminx.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
 import org.distorted.library.mesh.MeshBase;
@@ -120,6 +118,17 @@ public class TwistyPyraminx extends TwistyObject
   private static MeshBase[] mMeshes;
   private static float[] mRowChances;
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length];
+    final float stroke = 0.08f;
+    final float radius = 0.06f;
+    final float[] radii= {radius,radius,radius};
+    mStickers[0] = new ObjectSticker(STICKERS[0],null,radii,stroke);
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyPyraminx(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -358,14 +367,16 @@ public class TwistyPyraminx extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    float R = 0.06f;
-    float S = 0.08f;
-    float[] RS = new float[] {R,R,R};
+    return FACE_COLORS[face];
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[0], null, S, FACE_COLORS[face], RS);
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyRedi.java b/src/main/java/org/distorted/objects/TwistyRedi.java
index 71c54abc..b6fd2f01 100644
--- a/src/main/java/org/distorted/objects/TwistyRedi.java
+++ b/src/main/java/org/distorted/objects/TwistyRedi.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -195,6 +193,22 @@ public class TwistyRedi extends TwistyObject
   private static int[] mPossibleAxis, mPossibleLayers;
   private static int[] mNumOccurences;
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length];
+    final float R0 = 0.09f;
+    final float R1 = 0.06f;
+    final float[][] radii = { {R0,R0,R0,R0},{R1,R1,R1,R1,R1} };
+    final float[] strokes = { 0.09f,0.06f };
+
+    for(int s=0; s<STICKERS.length; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyRedi(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -372,21 +386,16 @@ public class TwistyRedi extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    int stickerType = face/COLORS;
-    float R,S;
+    return FACE_COLORS[face];
+    }
 
-    switch(stickerType)
-      {
-      case 0:  R = 0.09f; S = 0.09f; break;
-      case 1:  R = 0.06f; S = 0.06f; break;
-      default: R = 0.00f; S = 0.00f; break;
-      }
-    float[] RS = new float[] {R,R,R,R};
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], null, S, FACE_COLORS[face%COLORS], RS);
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyRex.java b/src/main/java/org/distorted/objects/TwistyRex.java
index fd120dca..6e453986 100644
--- a/src/main/java/org/distorted/objects/TwistyRex.java
+++ b/src/main/java/org/distorted/objects/TwistyRex.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.effect.VertexEffect;
 import org.distorted.library.effect.VertexEffectMove;
@@ -137,6 +135,33 @@ public class TwistyRex extends TwistyObject
 
   private static MeshBase mCornerMesh, mFaceMesh, mEdgeMesh;
 
+  private static final int NUM_STICKERS = 3;
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[NUM_STICKERS];
+
+    final float A = REX_D*SQ2;
+    final float B = (1-REX_D)*SQ2/2;
+    final float C = 1.0f;
+    final float D = 0.5f-REX_D;
+    final float E = (float)(Math.PI/15);
+    final float F = (float)(Math.PI/20);
+    final float R1= 0.02f;
+    final float R2= 0.04f;
+    final float R3= 0.06f;
+    final float[][] coords = { {A/2,-B/3,-A/2,-B/3,0,2*B/3},{-REX_D,0,0,-REX_D,+REX_D,0,0,+REX_D},{-C/2,D/3,C/2,D/3,0,-2*D/3} };
+    final float[][] angles = { { -E/2,E,E },null,{ F/10,-F,-F } };
+    final float[][] radii  = { {R1,R1,R1},{R2,R2,R2,R2},{0,0,R3} };
+    final float[] strokes = { 0.05f, 0.035f, 0.045f };
+
+    for(int s=0; s<NUM_STICKERS; s++)
+      {
+      mStickers[s] = new ObjectSticker(coords[s],angles[s],radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyRex(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -177,7 +202,7 @@ public class TwistyRex extends TwistyObject
 
   int getNumStickerTypes(int numLayers)
     {
-    return 3;
+    return NUM_STICKERS;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -549,46 +574,16 @@ public class TwistyRex extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    FactorySticker factory = FactorySticker.getInstance();
-
-    if( face<COLORS )
-      {
-      float S = 0.05f;
-      float R = 0.02f;
-      float[] RS = new float[] {R,R,R};
-      float ANGLE = (float)(Math.PI/15);
-      float F = REX_D*SQ2;
-      float G = (1-REX_D)*SQ2/2;
-      float[] vertices = new float[] { F/2, -G/3, -F/2, -G/3, 0, 2*G/3 };
-      float[] angles   = new float[] { -ANGLE/2, ANGLE, ANGLE };
-
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, angles, S, FACE_COLORS[face%COLORS], RS);
-      }
-    else if( face<2*COLORS )
-      {
-      float S = 0.035f;
-      float R = 0.040f;
-      float[] RS = new float[] {R,R,R,R};
-      float[] vertices = { -REX_D,0.0f, 0.0f, -REX_D, +REX_D, 0.0f, 0.0f, +REX_D};
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, null, S, FACE_COLORS[face%COLORS], RS);
-      }
-    else
-      {
-      float S = 0.045f;
-      float R = 0.060f;
-      float[] RS = new float[] {0,0,R};
+    return FACE_COLORS[face];
+    }
 
-      float ANGLE = (float)(Math.PI/20);
-      float F = 1.0f;
-      float G = 0.5f-REX_D;
-      float[] vertices = new float[] { -F/2, G/3, F/2, G/3, 0, -2*G/3 };
-      float[] angles   = new float[] { ANGLE/10, -ANGLE, -ANGLE };
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-      factory.drawRoundedPolygon(canvas, paint, left, top, vertices, angles, S, FACE_COLORS[face%COLORS], RS);
-      }
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistySkewb.java b/src/main/java/org/distorted/objects/TwistySkewb.java
index 9483cf91..d6dc846c 100644
--- a/src/main/java/org/distorted/objects/TwistySkewb.java
+++ b/src/main/java/org/distorted/objects/TwistySkewb.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -177,6 +175,24 @@ public class TwistySkewb extends TwistyObject
 
   private static MeshBase[] mMeshes;
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length+1];
+    final float R1 = 0.025f;
+    final float R2 = 0.025f;
+    final float R3 = 0.055f;
+    final float[][] radii  = { { R1,R1,R1 },{ R2,R2,R2 },{ R3,R3,R3,R3 } };
+    final float[] strokes = { 0.045f, 0.035f, 0.035f };
+
+    for(int s=0; s<STICKERS.length+1; s++)
+      {
+      int index = s<2 ? 0:1;
+      mStickers[s] = new ObjectSticker(STICKERS[index],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistySkewb(int size, Static4D quat, DistortedTexture texture,
@@ -572,22 +588,16 @@ public class TwistySkewb extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getColor(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    float R,S;
-    float[] RS;
-    int index, cubitType = face/COLORS;
+    return FACE_COLORS[face];
+    }
 
-    switch(cubitType)
-      {
-      case 0 : R = 0.025f; S = 0.045f; index= 0; RS = new float[] {R,R,R  }; break;
-      case 1 : R = 0.025f; S = 0.035f; index= 0; RS = new float[] {R,R,R  }; break;
-      default: R = 0.055f; S = 0.035f; index= 1; RS = new float[] {R,R,R,R}; break;
-      }
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[index], null, S, FACE_COLORS[face%COLORS], RS);
+  ObjectSticker retSticker(int face)
+    {
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistySquare.java b/src/main/java/org/distorted/objects/TwistySquare.java
index 768da686..50e98939 100644
--- a/src/main/java/org/distorted/objects/TwistySquare.java
+++ b/src/main/java/org/distorted/objects/TwistySquare.java
@@ -274,6 +274,13 @@ abstract class TwistySquare extends TwistyObject
     return new float[][] { {-0.5f,+0.5f}, {0.0f} };
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  int getColor(int face)
+    {
+    return FACE_COLORS[face];
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // PUBLIC API
 
diff --git a/src/main/java/org/distorted/objects/TwistySquare1.java b/src/main/java/org/distorted/objects/TwistySquare1.java
index bb9f7272..78a1cf2d 100644
--- a/src/main/java/org/distorted/objects/TwistySquare1.java
+++ b/src/main/java/org/distorted/objects/TwistySquare1.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -104,13 +102,13 @@ class TwistySquare1 extends TwistySquare
       { -0.2637079f, -0.38185397f, 0.38185397f, -0.38185397f, 0.38185397f, 0.2637079f, -0.5f, 0.5f } // corner top
     };
 
-  private static final int NUM_ST = STICKERS.length;
+  private static final int NUM_STICKERS = STICKERS.length;
 
   private static final int[][] mStickerType = new int[][]
     {
-      {  NUM_ST,NUM_ST,0,     1,     2,NUM_ST },
-      {       3,NUM_ST,4,NUM_ST,NUM_ST,NUM_ST },
-      {       5,NUM_ST,2,     2,NUM_ST,NUM_ST }
+      {  NUM_STICKERS,NUM_STICKERS,0,           1,           2,NUM_STICKERS },
+      {             3,NUM_STICKERS,4,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS },
+      {             5,NUM_STICKERS,2,           2,NUM_STICKERS,NUM_STICKERS }
     };
 
   // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4 ORANGE 5
@@ -149,6 +147,26 @@ class TwistySquare1 extends TwistySquare
   private final int[] mCornerQuat;
   private int mPermittedUp, mPermittedDo;
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[NUM_STICKERS];
+    final float R1 = 0.06f;
+    final float R2 = 0.04f;
+    final float R3 = 0.11f;
+    final float R4 = 0.03f;
+    final float R5 = 0.11f;
+    final float R6 = 0.08f;
+    final float[][] radii  = { {R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4},{R5,R5,R5,R5},{R6,R6,R6,R6} };
+    final float[] strokes = { 0.05f,0.04f,0.09f,0.05f,0.08f,0.08f };
+
+    for(int s=0; s<NUM_STICKERS; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistySquare1(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -221,26 +239,9 @@ class TwistySquare1 extends TwistySquare
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  ObjectSticker retSticker(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    int stickerType = face/COLORS;
-    float R,S;
-    float[] RS;
-
-    switch(stickerType)
-      {
-      case 0:  R = 0.06f; S = 0.05f; RS= new float[] {R,R,R,R}; break;
-      case 1:  R = 0.04f; S = 0.04f; RS= new float[] {R,R,R,R}; break;
-      case 2:  R = 0.11f; S = 0.09f; RS= new float[] {R,R,R,R}; break;
-      case 3:  R = 0.03f; S = 0.05f; RS= new float[] {R,R,R  }; break;
-      case 4:  R = 0.11f; S = 0.08f; RS= new float[] {R,R,R,R}; break;
-      case 5:  R = 0.08f; S = 0.08f; RS= new float[] {R,R,R,R}; break;
-      default: R = 0.00f; S = 0.00f; RS= new float[] {R,R,R,R}; break;
-      }
-
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], null, S, FACE_COLORS[face%COLORS], RS);
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -254,7 +255,7 @@ class TwistySquare1 extends TwistySquare
 
   int getNumStickerTypes(int numLayers)
     {
-    return STICKERS.length;
+    return NUM_STICKERS;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistySquare2.java b/src/main/java/org/distorted/objects/TwistySquare2.java
index e3e77b05..77fc6e91 100644
--- a/src/main/java/org/distorted/objects/TwistySquare2.java
+++ b/src/main/java/org/distorted/objects/TwistySquare2.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -114,14 +112,14 @@ class TwistySquare2 extends TwistySquare
       { -0.11602539f, -0.25f, 0.4330127f, -0.25f, -0.3169873f, 0.5f }                     // corner top
     };
 
-  private static final int NUM_ST = STICKERS.length;
+  private static final int NUM_STICKERS = STICKERS.length;
 
   private static final int[][] mStickerType = new int[][]
     {
-      {  NUM_ST,NUM_ST,0,     1,     2,NUM_ST },
-      {       3,NUM_ST,4,NUM_ST,NUM_ST,NUM_ST },
-      {       5,NUM_ST,2,NUM_ST,NUM_ST,NUM_ST },
-      {  NUM_ST,     5,2,NUM_ST,NUM_ST,NUM_ST }
+      {  NUM_STICKERS,NUM_STICKERS,0,           1,           2,NUM_STICKERS },
+      {             3,NUM_STICKERS,4,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS },
+      {             5,NUM_STICKERS,2,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS },
+      {  NUM_STICKERS,           5,2,NUM_STICKERS,NUM_STICKERS,NUM_STICKERS }
     };
 
   // YELLOW 0 WHITE 1 BLUE 2 GREEN 3 RED 4 ORANGE 5
@@ -158,6 +156,26 @@ class TwistySquare2 extends TwistySquare
       { 3, 0, 4, 0, 0, 0 },
     };
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[NUM_STICKERS];
+    final float R1 = 0.06f;
+    final float R2 = 0.04f;
+    final float R3 = 0.11f;
+    final float R4 = 0.03f;
+    final float R5 = 0.11f;
+    final float R6 = 0.025f;
+    final float[][] radii  = { {R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3},{R4,R4,R4},{R5,R5,R5,R5},{R6,R6,R6} };
+    final float[] strokes = { 0.05f,0.04f,0.09f,0.05f,0.08f,0.06f };
+
+    for(int s=0; s<NUM_STICKERS; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistySquare2(int size, Static4D quat, DistortedTexture texture, MeshSquare mesh,
@@ -226,26 +244,9 @@ class TwistySquare2 extends TwistySquare
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  ObjectSticker retSticker(int face)
     {
-    int COLORS = FACE_COLORS.length;
-    int stickerType = face/COLORS;
-    float R,S;
-    float[] RS;
-
-    switch(stickerType)
-      {
-      case 0:  R = 0.060f; S = 0.05f; RS= new float[] {R,R,R,R}; break;
-      case 1:  R = 0.040f; S = 0.04f; RS= new float[] {R,R,R,R}; break;
-      case 2:  R = 0.110f; S = 0.09f; RS= new float[] {R,R,R,R}; break;
-      case 3:  R = 0.030f; S = 0.05f; RS= new float[] {R,R,R  }; break;
-      case 4:  R = 0.110f; S = 0.08f; RS= new float[] {R,R,R,R}; break;
-      case 5:  R = 0.025f; S = 0.06f; RS= new float[] {R,R,R  }; break;
-      default: R = 0.000f; S = 0.00f; RS= new float[] {R,R,R,R}; break;
-      }
-
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], null, S, FACE_COLORS[face%COLORS], RS);
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -259,7 +260,7 @@ class TwistySquare2 extends TwistySquare
 
   int getNumStickerTypes(int numLayers)
     {
-    return STICKERS.length;
+    return NUM_STICKERS;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/TwistyUltimate.java b/src/main/java/org/distorted/objects/TwistyUltimate.java
index 59d75bf4..ea3f9857 100644
--- a/src/main/java/org/distorted/objects/TwistyUltimate.java
+++ b/src/main/java/org/distorted/objects/TwistyUltimate.java
@@ -20,11 +20,9 @@
 package org.distorted.objects;
 
 import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 
 import org.distorted.helpers.FactoryCubit;
-import org.distorted.helpers.FactorySticker;
+import org.distorted.helpers.ObjectSticker;
 import org.distorted.library.effect.MatrixEffectQuaternion;
 import org.distorted.library.main.DistortedEffects;
 import org.distorted.library.main.DistortedTexture;
@@ -221,6 +219,23 @@ class TwistyUltimate extends TwistyObject
 
   private static MeshBase[] mMeshes;
 
+  private static final ObjectSticker[] mStickers;
+
+  static
+    {
+    mStickers = new ObjectSticker[STICKERS.length];
+    final float R1 = 0.08f;
+    final float R2 = 0.13f;
+    final float R3 = 0.11f;
+    final float[][] radii  = { {R1,R1,R1,R1,R1},{R2,R2,R2,R2},{R3,R3,R3,R3} };
+    final float[] strokes = { 0.07f, 0.09f, 0.08f };
+
+    for(int s=0; s<STICKERS.length; s++)
+      {
+      mStickers[s] = new ObjectSticker(STICKERS[s],null,radii[s],strokes[s]);
+      }
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   TwistyUltimate(int size, Static4D quat, DistortedTexture texture,
@@ -342,30 +357,23 @@ class TwistyUltimate extends TwistyObject
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void createFaceTexture(Canvas canvas, Paint paint, int face, int left, int top)
+  int getFaceColor(int cubit, int cubitface, int size)
     {
-    int COLORS = FACE_COLORS.length;
-    int stickerType = face/COLORS;
-    float R,S;
-    float[] RS;
+    return mFaceMap[cubit][cubitface];
+    }
 
-    switch(stickerType)
-      {
-      case 0:  R = 0.08f; S = 0.07f; RS= new float[] {R,R,R,R,R}; break;
-      case 1:  R = 0.13f; S = 0.09f; RS= new float[] {R,R,R,R  }; break;
-      case 2:  R = 0.11f; S = 0.08f; RS= new float[] {R,R,R,R  }; break;
-      default: R = 0.00f; S = 0.00f; RS= new float[] {R,R,R,R  }; break;
-      }
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
-    FactorySticker factory = FactorySticker.getInstance();
-    factory.drawRoundedPolygon(canvas, paint, left, top, STICKERS[stickerType], null, S, FACE_COLORS[face%COLORS], RS);
+  int getColor(int face)
+    {
+    return FACE_COLORS[face];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  int getFaceColor(int cubit, int cubitface, int size)
+  ObjectSticker retSticker(int face)
     {
-    return mFaceMap[cubit][cubitface];
+    return mStickers[face/NUM_FACES];
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
