commit 55fb45c2c6b8820f8240cc903434808c675033ba
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Wed Oct 7 00:28:35 2020 +0100

    More unification in CubitFactory.

diff --git a/src/main/java/org/distorted/objects/CubitFactory.java b/src/main/java/org/distorted/objects/CubitFactory.java
index 2e03f0d4..629c98e5 100644
--- a/src/main/java/org/distorted/objects/CubitFactory.java
+++ b/src/main/java/org/distorted/objects/CubitFactory.java
@@ -27,7 +27,6 @@ import org.distorted.library.effect.VertexEffectScale;
 import org.distorted.library.mesh.MeshBase;
 import org.distorted.library.mesh.MeshJoined;
 import org.distorted.library.mesh.MeshPolygon;
-import org.distorted.library.mesh.MeshTriangle;
 import org.distorted.library.type.Static1D;
 import org.distorted.library.type.Static3D;
 import org.distorted.library.type.Static4D;
@@ -82,9 +81,8 @@ public class CubitFactory
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// CUBE
 
-  MeshBase createCubeMesh(int index)
+  MeshBase createFacesCube(int index)
     {
     final int MESHES=6;
     MeshBase[] meshes = new MeshPolygon[MESHES];
@@ -102,31 +100,31 @@ public class CubitFactory
                                      1.0f-D/2,-D*0.55f,
                                      1.0f-D  ,-D*0.25f,
                                      1.0f-2*D, 0.0f,
-                                     0.50f, 0.040f,
-                                     0.0f, 0.048f };
+                                     0.50f   , 0.040f,
+                                     0.0f    , 0.048f };
                extraI = 2;
                extraV = 2;
                break;
-      case 1 : bands = new float[] { 1.0f    ,-D,
+      case 1 : bands = new float[] { 1.0f       ,-D,
                                      1.0f-D*1.2f,-D*0.55f,
-                                     1.0f-2*D, 0.0f,
-                                     0.50f, 0.040f,
-                                     0.0f, 0.048f };
+                                     1.0f-2*D   , 0.0f,
+                                     0.50f      , 0.040f,
+                                     0.0f       , 0.048f };
                extraI = 2;
                extraV = 2;
                break;
-      case 2 : bands = new float[] { 1.0f    ,-D,
+      case 2 : bands = new float[] { 1.0f       ,-D,
                                      1.0f-D*1.2f,-D*0.55f,
-                                     1.0f-2*D, 0.0f,
-                                     0.50f, 0.040f,
-                                     0.0f, 0.048f };
+                                     1.0f-2*D   , 0.0f,
+                                     0.50f      , 0.040f,
+                                     0.0f       , 0.048f };
                extraI = 1;
                extraV = 2;
                break;
       default: bands = new float[] { 1.0f    ,-D,
                                      1.0f-2*D, 0.0f,
-                                     0.50f, 0.025f,
-                                     0.0f, 0.030f };
+                                     0.50f   , 0.025f,
+                                     0.0f    , 0.030f };
                extraI = 1;
                extraV = 1;
                break;
@@ -142,57 +140,12 @@ public class CubitFactory
       meshes[i].setEffectAssociation(0,association,0);
       }
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D axisY   = new Static3D(0,1,0);
-    Static3D axisX   = new Static3D(1,0,0);
-    Static3D center  = new Static3D(0,0,0);
-    Static1D angle90 = new Static1D(90);
-    Static1D angle180= new Static1D(180);
-    Static1D angle270= new Static1D(270);
-
-    VertexEffect effect0 = new VertexEffectMove(new Static3D(0,0,+0.5f));
-    VertexEffect effect1 = new VertexEffectRotate( angle180, axisX, center );
-    VertexEffect effect2 = new VertexEffectRotate( angle90 , axisX, center );
-    VertexEffect effect3 = new VertexEffectRotate( angle270, axisX, center );
-    VertexEffect effect4 = new VertexEffectRotate( angle270, axisY, center );
-    VertexEffect effect5 = new VertexEffectRotate( angle90 , axisY, center );
-
-    effect0.setMeshAssociation(63,-1);  // all 6 sides
-    effect1.setMeshAssociation(32,-1);  // back
-    effect2.setMeshAssociation( 8,-1);  // bottom
-    effect3.setMeshAssociation( 4,-1);  // top
-    effect4.setMeshAssociation( 2,-1);  // left
-    effect5.setMeshAssociation( 1,-1);  // right
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-
-    Static3D[] verticesCubit = new Static3D[8];
-    verticesCubit[0] = new Static3D(+0.5f,+0.5f,+0.5f);
-    verticesCubit[1] = new Static3D(+0.5f,+0.5f,-0.5f);
-    verticesCubit[2] = new Static3D(+0.5f,-0.5f,+0.5f);
-    verticesCubit[3] = new Static3D(+0.5f,-0.5f,-0.5f);
-    verticesCubit[4] = new Static3D(-0.5f,+0.5f,+0.5f);
-    verticesCubit[5] = new Static3D(-0.5f,+0.5f,-0.5f);
-    verticesCubit[6] = new Static3D(-0.5f,-0.5f,+0.5f);
-    verticesCubit[7] = new Static3D(-0.5f,-0.5f,-0.5f);
-
-    roundCorners(mesh,center,verticesCubit,0.06f,0.12f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// SKEWB
 
-  MeshBase createSkewbCornerMesh()
+  MeshBase createFacesSkewbCorner()
     {
     float D = 0.02f;
     float E = 0.5f;
@@ -227,76 +180,12 @@ public class CubitFactory
     meshes[5] = meshes[3].copy(true);
     meshes[5].setEffectAssociation(0,32,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D axisX  = new Static3D(1,0,0);
-    Static3D axisY  = new Static3D(0,1,0);
-    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
-    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
-    Static1D angle1 = new Static1D(+90);
-    Static1D angle2 = new Static1D(-90);
-    Static1D angle3 = new Static1D(-15);
-    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
-    Static1D angle5 = new Static1D(120);
-    Static1D angle6 = new Static1D(240);
-    Static3D center1= new Static3D(0,0,0);
-    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
-    Static3D move1  = new Static3D(-E/4,-E/4,0);
-    Static3D move2  = new Static3D(-0.5f,-0.5f,-0.5f);
-
-    VertexEffect effect0 = new VertexEffectMove(move1);
-    VertexEffect effect1 = new VertexEffectScale(new Static3D(1,1,-1));
-    VertexEffect effect2 = new VertexEffectRotate(angle1,axisX,center1);
-    VertexEffect effect3 = new VertexEffectRotate(angle2,axisY,center1);
-    VertexEffect effect4 = new VertexEffectMove(move2);
-    VertexEffect effect5 = new VertexEffectRotate(angle1,axisX,center2);
-    VertexEffect effect6 = new VertexEffectRotate(angle3,axisY,center2);
-    VertexEffect effect7 = new VertexEffectRotate(angle4,axis0,center2);
-    VertexEffect effect8 = new VertexEffectRotate(angle5,axis1,center2);
-    VertexEffect effect9 = new VertexEffectRotate(angle6,axis1,center2);
-
-    effect0.setMeshAssociation( 7,-1);  // meshes 0,1,2
-    effect1.setMeshAssociation( 6,-1);  // meshes 1,2
-    effect2.setMeshAssociation( 2,-1);  // mesh 1
-    effect3.setMeshAssociation( 4,-1);  // mesh 2
-    effect4.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect5.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect6.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect7.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect8.setMeshAssociation(16,-1);  // mesh 4
-    effect9.setMeshAssociation(32,-1);  // mesh 5
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-    mesh.apply(effect6);
-    mesh.apply(effect7);
-    mesh.apply(effect8);
-    mesh.apply(effect9);
-
-    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
-
-    Static3D[] verticesType1 = new Static3D[1];
-    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
-    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
-
-    Static3D[] verticesType2 = new Static3D[3];
-    verticesType2[0] = new Static3D(-E, 0, 0);
-    verticesType2[1] = new Static3D( 0,-E, 0);
-    verticesType2[2] = new Static3D( 0, 0,-E);
-    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createSkewbFaceMesh()
+  MeshBase createFacesSkewbFace()
     {
     float D = 0.03f;
     float E = SQ2/4;
@@ -326,53 +215,12 @@ public class CubitFactory
     meshes[4] = meshes[1].copy(true);
     meshes[4].setEffectAssociation(0,16,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D center = new Static3D(0,0,0);
-    Static3D axisX  = new Static3D(1,0,0);
-    Static3D axisZ  = new Static3D(0,0,1);
-    float angle = -(float)((180.0f/Math.PI)*Math.acos(SQ3/3));
-
-    VertexEffect effect0 = new VertexEffectRotate( new Static1D(angle), axisX, center);
-    VertexEffect effect1 = new VertexEffectRotate( new Static1D(  135), axisZ, center);
-    VertexEffect effect2 = new VertexEffectRotate( new Static1D(   45), axisZ, center);
-    VertexEffect effect3 = new VertexEffectRotate( new Static1D(  -45), axisZ, center);
-    VertexEffect effect4 = new VertexEffectRotate( new Static1D( -135), axisZ, center);
-    VertexEffect effect5 = new VertexEffectMove( new Static3D(0,0,-0.5f) );
-
-    effect0.setMeshAssociation(30,-1);  // meshes 1,2,3,4
-    effect1.setMeshAssociation( 2,-1);  // mesh 1
-    effect2.setMeshAssociation( 5,-1);  // meshes 0,2
-    effect3.setMeshAssociation( 8,-1);  // mesh 3
-    effect4.setMeshAssociation(16,-1);  // mesh 4
-    effect5.setMeshAssociation(30,-1);  // meshes 1,2,3,4
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-
-    Static3D roundingCenter = new Static3D(0,0,-0.2f);
-
-    Static3D[] vertices = new Static3D[4];
-    vertices[0] = new Static3D(-E*SQ2,      0, 0);
-    vertices[1] = new Static3D(+E*SQ2,      0, 0);
-    vertices[2] = new Static3D(     0, -E*SQ2, 0);
-    vertices[3] = new Static3D(     0, +E*SQ2, 0);
-    roundCorners(mesh,roundingCenter,vertices,0.10f,0.10f);
-
-    mesh.mergeEffComponents();
-    mesh.addEmptyTexComponent();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// SKEWB DIAMOND / PYRAMINX
 
-  MeshBase createOctaMesh()
+  MeshBase createFacesOcta()
     {
     int association = 1;
 
@@ -401,60 +249,12 @@ public class CubitFactory
       meshes[i].setEffectAssociation(0,association,0);
       }
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static1D alpha = new Static1D((float)(-(180/Math.PI)*Math.asin(SQ3/3)));
-    Static1D angle1= new Static1D( 90);
-    Static1D angle2= new Static1D(180);
-    Static1D angle3= new Static1D(270);
-
-    Static3D move1 = new Static3D(0,SQ2/2-SQ3/3,0);
-
-    Static3D axisX = new Static3D(1,0,0);
-    Static3D axisY = new Static3D(0,1,0);
-
-    Static3D cent0 = new Static3D(0,0,0);
-    Static3D cent1 = new Static3D(0,SQ2/2,0);
-
-    Static3D flipY = new Static3D( 1,-1, 1);
-
-    VertexEffect effect0 = new VertexEffectMove(move1);
-    VertexEffect effect1 = new VertexEffectRotate(alpha , axisX, cent1);
-    VertexEffect effect2 = new VertexEffectRotate(angle1, axisY, cent0);
-    VertexEffect effect3 = new VertexEffectRotate(angle2, axisY, cent0);
-    VertexEffect effect4 = new VertexEffectRotate(angle3, axisY, cent0);
-    VertexEffect effect5 = new VertexEffectScale(flipY);
-
-    effect2.setMeshAssociation ( 34,-1); // apply to meshes 1 & 5
-    effect3.setMeshAssociation ( 68,-1); // apply to meshes 2 & 6
-    effect4.setMeshAssociation (136,-1); // apply to meshes 3 & 7
-    effect5.setMeshAssociation (240,-1); // apply to meshes 4,5,6,7
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-
-    Static3D[] verticesRound = new Static3D[6];
-    verticesRound[0] = new Static3D(    0, SQ2/2,    0 );
-    verticesRound[1] = new Static3D( 0.5f,     0, 0.5f );
-    verticesRound[2] = new Static3D(-0.5f,     0, 0.5f );
-    verticesRound[3] = new Static3D(    0,-SQ2/2,    0 );
-    verticesRound[4] = new Static3D(-0.5f,     0,-0.5f );
-    verticesRound[5] = new Static3D( 0.5f,     0,-0.5f );
-
-    roundCorners(mesh,cent0,verticesRound,0.06f,0.20f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createTetraMesh()
+  MeshBase createFacesTetra()
     {
     MeshBase[] meshes = new MeshBase[4];
     int association = 1;
@@ -483,66 +283,13 @@ public class CubitFactory
       meshes[i].setEffectAssociation(0,association,0);
       }
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D flipZ = new Static3D( 1, 1,-1);
-
-    Static1D alpha = new Static1D((float)(-(180/Math.PI)*Math.asin(SQ3/3)));
-    Static1D angle1= new Static1D( 90);
-    Static1D angle2= new Static1D(180);
-    Static3D move1 = new Static3D(0,SQ2/4-SQ3/6,0);
-
-    Static3D axisX = new Static3D(1,0,0);
-    Static3D axisY = new Static3D(0,1,0);
-    Static3D axisZ = new Static3D(0,0,1);
-
-    Static3D cent0 = new Static3D(0,0,0);
-    Static3D cent1 = new Static3D(0,SQ2/4,0);
-
-    VertexEffect effect0 = new VertexEffectRotate(angle2, axisZ, cent0);
-    VertexEffect effect1 = new VertexEffectMove(move1);
-    VertexEffect effect2 = new VertexEffectRotate(alpha , axisX, cent1);
-    VertexEffect effect3 = new VertexEffectScale(flipZ);
-    VertexEffect effect4 = new VertexEffectRotate(angle1, axisY, cent0);
-    VertexEffect effect5 = new VertexEffectRotate(angle2, axisZ, cent0);
-
-    effect0.setMeshAssociation(15,-1); // meshes 0,1,2,3
-    effect1.setMeshAssociation(15,-1); // meshes 0,1,2,3
-    effect2.setMeshAssociation(15,-1); // meshes 0,1,2,3
-    effect3.setMeshAssociation(10,-1); // meshes 1 & 3
-    effect4.setMeshAssociation(12,-1); // meshes 2 & 3
-    effect5.setMeshAssociation(12,-1); // meshes 2 & 3
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-
-    Static3D[] verticesRound = new Static3D[4];
-    verticesRound[0] = new Static3D(-0.5f,+SQ2/4,   0 );
-    verticesRound[1] = new Static3D(+0.5f,+SQ2/4,   0 );
-    verticesRound[2] = new Static3D(    0,-SQ2/4,+0.5f);
-    verticesRound[3] = new Static3D(    0,-SQ2/4,-0.5f);
-    roundCorners(mesh,cent0,verticesRound,0.08f,0.15f);
-
-    mesh.mergeEffComponents();
-    mesh.addEmptyTexComponent();
-    mesh.addEmptyTexComponent();
-    mesh.addEmptyTexComponent();
-    mesh.addEmptyTexComponent();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// DINO
 
-  MeshBase createDinoMesh()
+  MeshBase createFacesDino()
     {
-    final float ANGLE = (float)((180/Math.PI)*(Math.atan(SQ2)));
-
     final int MESHES=4;
 
     float D = 0.02f;
@@ -576,69 +323,12 @@ public class CubitFactory
     meshes[3] = meshes[2].copy(true);
     meshes[3].setEffectAssociation(0,8,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static1D angle1 = new Static1D(+ANGLE);
-    Static1D angle2 = new Static1D(-ANGLE);
-
-    Static3D axisX  = new Static3D(1,0,0);
-    Static3D axisY  = new Static3D(0,1,0);
-    Static3D axisZ  = new Static3D(0,-1,1);
-
-    Static3D center0= new Static3D(0,0,0);
-    Static3D center1= new Static3D(0,-3*F,0);
-
-    VertexEffect effect0 = new VertexEffectScale ( new Static3D(3,3,3) );
-    VertexEffect effect1 = new VertexEffectMove  ( new Static3D(0,-F,0) );
-    VertexEffect effect2 = new VertexEffectRotate( new Static1D(90), axisX, center0 );
-    VertexEffect effect3 = new VertexEffectScale ( new Static3D(1,-1,1) );
-    VertexEffect effect4 = new VertexEffectMove  ( new Static3D(3*E/2,E*(SQ3/2)-3*F,0) );
-    VertexEffect effect5 = new VertexEffectRotate( new Static1D(+90), axisY, center1 );
-    VertexEffect effect6 = new VertexEffectScale ( new Static3D(-1,1,1) );
-    VertexEffect effect7 = new VertexEffectRotate( new Static1D( 45), axisX, center1 );
-    VertexEffect effect8 = new VertexEffectRotate( angle1           , axisZ, center1 );
-    VertexEffect effect9 = new VertexEffectRotate( angle2           , axisZ, center1 );
-
-    effect0.setMeshAssociation(15,-1);  // apply to meshes 0,1,2,3
-    effect1.setMeshAssociation( 3,-1);  // apply to meshes 0,1
-    effect2.setMeshAssociation( 2,-1);  // apply to mesh 1
-    effect3.setMeshAssociation( 2,-1);  // apply to mesh 0
-    effect4.setMeshAssociation(12,-1);  // apply to meshes 2,3
-    effect5.setMeshAssociation(12,-1);  // apply to meshes 2,3
-    effect6.setMeshAssociation( 8,-1);  // apply to mesh 3
-    effect7.setMeshAssociation(12,-1);  // apply to meshes 2,3
-    effect8.setMeshAssociation( 4,-1);  // apply to mesh 2
-    effect9.setMeshAssociation( 8,-1);  // apply to mesh 3
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-    mesh.apply(effect6);
-    mesh.apply(effect7);
-    mesh.apply(effect8);
-    mesh.apply(effect9);
-
-    Static3D roundingCenter = new Static3D(0.0f, -1.5f*F, -1.5f*F);
-
-    Static3D[] verticesRound = new Static3D[4];
-    verticesRound[0] = new Static3D(     0,-3*F,    0 );
-    verticesRound[1] = new Static3D(     0,   0, -3*F );
-    verticesRound[2] = new Static3D(  -3*F,   0,    0 );
-    verticesRound[3] = new Static3D(  +3*F,   0,    0 );
-    roundCorners(mesh,roundingCenter,verticesRound,0.10f,0.40f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Helicopter
 
-  MeshBase createHelicopterCornerMesh()
+  MeshBase createFacesHelicopterCorner()
     {
     float D = 0.02f;
     float E = 0.5f;
@@ -673,76 +363,12 @@ public class CubitFactory
     meshes[5] = meshes[3].copy(true);
     meshes[5].setEffectAssociation(0,32,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D axisX  = new Static3D(1,0,0);
-    Static3D axisY  = new Static3D(0,1,0);
-    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
-    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
-    Static1D angle1 = new Static1D(+90);
-    Static1D angle2 = new Static1D(-90);
-    Static1D angle3 = new Static1D(-135);
-    Static1D angle4 = new Static1D(90);
-    Static1D angle5 = new Static1D(120);
-    Static1D angle6 = new Static1D(240);
-    Static3D center1= new Static3D(0,0,0);
-    Static3D center2= new Static3D(-0.25f,-0.25f,-0.25f);
-    Static3D move1  = new Static3D(-E/4,-E/4,0);
-    Static3D move2  = new Static3D(-0.25f,(-1.0f/6)-0.25f,-0.25f);
-
-    VertexEffect effect0 = new VertexEffectMove(move1);
-    VertexEffect effect1 = new VertexEffectScale(new Static3D(1,1,-1));
-    VertexEffect effect2 = new VertexEffectRotate(angle1,axisX,center1);
-    VertexEffect effect3 = new VertexEffectRotate(angle2,axisY,center1);
-    VertexEffect effect4 = new VertexEffectMove(move2);
-    VertexEffect effect5 = new VertexEffectRotate(angle1,axisX,center2);
-    VertexEffect effect6 = new VertexEffectRotate(angle3,axisY,center2);
-    VertexEffect effect7 = new VertexEffectRotate(angle4,axis0,center2);
-    VertexEffect effect8 = new VertexEffectRotate(angle5,axis1,center2);
-    VertexEffect effect9 = new VertexEffectRotate(angle6,axis1,center2);
-
-    effect0.setMeshAssociation( 7,-1);  // meshes 0,1,2
-    effect1.setMeshAssociation( 6,-1);  // meshes 1,2
-    effect2.setMeshAssociation( 2,-1);  // mesh 1
-    effect3.setMeshAssociation( 4,-1);  // mesh 2
-    effect4.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect5.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect6.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect7.setMeshAssociation(56,-1);  // meshes 3,4,5
-    effect8.setMeshAssociation(16,-1);  // mesh 4
-    effect9.setMeshAssociation(32,-1);  // mesh 5
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-    mesh.apply(effect6);
-    mesh.apply(effect7);
-    mesh.apply(effect8);
-    mesh.apply(effect9);
-
-    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
-
-    Static3D[] verticesType1 = new Static3D[1];
-    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
-    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
-
-    Static3D[] verticesType2 = new Static3D[3];
-    verticesType2[0] = new Static3D(-E, 0, 0);
-    verticesType2[1] = new Static3D( 0,-E, 0);
-    verticesType2[2] = new Static3D( 0, 0,-E);
-    roundCorners(mesh,roundingCenter,verticesType2,0.10f,0.20f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createHelicopterFaceMesh()
+  MeshBase createFacesHelicopterFace()
     {
     MeshBase[] meshes = new MeshBase[4];
 
@@ -784,79 +410,12 @@ public class CubitFactory
     meshes[3] = meshes[2].copy(true);
     meshes[3].setEffectAssociation(0,8,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D move0  = new Static3D(-E/4, -E/4, 0);
-    Static3D move1  = new Static3D(-(SQ2/24)-E/2, -(SQ2/24)-E/2, 0);
-    Static3D move2  = new Static3D(-E/2, F/3, 0);
-    Static3D move3  = new Static3D(+E/2, F/3, 0);
-    Static3D move4  = new Static3D(+E/3,+E/3, 0);
-    Static1D angle1 = new Static1D(135);
-    Static1D angle2 = new Static1D(90);
-    Static1D angle3 = new Static1D(-90);
-    Static1D angle4 = new Static1D(-135);
-    Static3D axisX  = new Static3D(1,0,0);
-    Static3D axisY  = new Static3D(0,1,0);
-    Static3D axisZ  = new Static3D(0,0,1);
-    Static3D axis1  = new Static3D(1,-1,0);
-    Static3D center = new Static3D(0,0,0);
-    Static3D center1= new Static3D(-E/2,-E/2,0);
-
-    VertexEffect effect0 = new VertexEffectMove(move0);
-    VertexEffect effect1 = new VertexEffectRotate(angle1, axisZ, center);
-    VertexEffect effect2 = new VertexEffectMove(move1);
-    VertexEffect effect3 = new VertexEffectRotate(angle2, axis1, center1);
-    VertexEffect effect4 = new VertexEffectMove(move2);
-    VertexEffect effect5 = new VertexEffectMove(move3);
-    VertexEffect effect6 = new VertexEffectRotate(angle3, axisZ, center);
-    VertexEffect effect7 = new VertexEffectRotate(angle4, axisX, center);
-    VertexEffect effect8 = new VertexEffectRotate(angle1, axisY, center);
-    VertexEffect effect9 = new VertexEffectMove(move4);
-
-    effect0.setMeshAssociation( 1,-1);  // mesh 0
-    effect1.setMeshAssociation( 2,-1);  // mesh 1
-    effect2.setMeshAssociation( 2,-1);  // mesh 1
-    effect3.setMeshAssociation( 2,-1);  // mesh 1
-    effect4.setMeshAssociation( 4,-1);  // mesh 2
-    effect5.setMeshAssociation( 8,-1);  // mesh 3
-    effect6.setMeshAssociation( 8,-1);  // mesh 3
-    effect7.setMeshAssociation( 4,-1);  // mesh 2
-    effect8.setMeshAssociation( 8,-1);  // mesh 3
-    effect9.setMeshAssociation(15,-1);  // meshes 0,1,2,3
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-    mesh.apply(effect6);
-    mesh.apply(effect7);
-    mesh.apply(effect8);
-    mesh.apply(effect9);
-
-    Static3D roundingCenter = new Static3D(-E/2 + E/3,-E/2 + E/3,-E/2);
-
-    Static3D[] verticesType1 = new Static3D[1];
-    verticesType1[0] = new Static3D(E/3,E/3,0.0f);
-    roundCorners(mesh,roundingCenter,verticesType1,0.06f,0.15f);
-
-    Static3D[] verticesType2 = new Static3D[2];
-    verticesType2[0] = new Static3D(-E+E/3, E/3  , 0);
-    verticesType2[1] = new Static3D( E/3  ,-E+E/3, 0);
-    roundCorners(mesh,roundingCenter,verticesType2,0.10f,0.20f);
-
-    mesh.mergeEffComponents();
-    mesh.addEmptyTexComponent();
-    mesh.addEmptyTexComponent();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Redi cube
 
-  MeshBase createRediEdgeMesh()
+  MeshBase createFacesRediEdge()
     {
     final int MESHES=6;
 
@@ -905,80 +464,12 @@ public class CubitFactory
     meshes[5] = meshes[4].copy(true);
     meshes[5].setEffectAssociation(0,32,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
-
-    Static3D move0 = new Static3D(0.0f, -0.5f, 0.0f);
-    Static3D move1 = new Static3D(0.25f, -0.25f, 0.0f);
-    Static3D move2 = new Static3D(0.5f, 0.0f, 0.0f);
-    Static3D move3 = new Static3D(0.0f, (SQ3-6)/8, (SQ3-6)/8);
-    Static3D flipZ = new Static3D(1,1,-1);
-    Static3D flipX = new Static3D(-1,1,1);
-    Static3D scale = new Static3D(2,2,2);
-    Static3D cent0 = new Static3D(0,0, 0);
-    Static3D cent1 = new Static3D(0,0, -1.5f);
-    Static3D axisX = new Static3D(1,0, 0);
-    Static3D axisY = new Static3D(0,1, 0);
-    Static3D axis  = new Static3D(0,SQ2/2,-SQ2/2);
-    Static1D angle1= new Static1D(90);
-    Static1D angle2= new Static1D(45);
-    Static1D angle3= new Static1D( (float)(180/Math.PI*Math.acos(SQ3/3)) );
-
-    VertexEffect effect0 = new VertexEffectScale(scale);
-    VertexEffect effect1 = new VertexEffectMove(move0);
-    VertexEffect effect2 = new VertexEffectScale(flipZ);
-    VertexEffect effect3 = new VertexEffectRotate(angle1,axisX,cent0);
-    VertexEffect effect4 = new VertexEffectMove(move1);
-    VertexEffect effect5 = new VertexEffectRotate(angle1,axisY,cent0);
-    VertexEffect effect6 = new VertexEffectMove(move2);
-    VertexEffect effect7 = new VertexEffectScale(flipX);
-    VertexEffect effect8 = new VertexEffectRotate(angle2,axisX,cent0);
-    VertexEffect effect9 = new VertexEffectMove(move3);
-    VertexEffect effect10= new VertexEffectRotate(angle3,axis ,cent1);
-    VertexEffect effect11= new VertexEffectScale(flipX);
-
-    effect0.setMeshAssociation(63,-1);  // meshes 0,1,2,3,4,5
-    effect1.setMeshAssociation( 3,-1);  // meshes 0,1
-    effect2.setMeshAssociation( 2,-1);  // mesh 1
-    effect3.setMeshAssociation( 2,-1);  // mesh 1
-    effect4.setMeshAssociation(12,-1);  // meshes 2,3
-    effect5.setMeshAssociation(60,-1);  // meshes 2,3,4,5
-    effect6.setMeshAssociation(12,-1);  // meshes 2,3
-    effect7.setMeshAssociation( 8,-1);  // mesh 3
-    effect8.setMeshAssociation(48,-1);  // meshes 4,5
-    effect9.setMeshAssociation(48,-1);  // meshes 4,5
-    effect10.setMeshAssociation(48,-1); // meshes 4,5
-    effect11.setMeshAssociation(32,-1); // mesh 5
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
-    mesh.apply(effect6);
-    mesh.apply(effect7);
-    mesh.apply(effect8);
-    mesh.apply(effect9);
-    mesh.apply(effect10);
-    mesh.apply(effect11);
-
-    Static3D center = new Static3D(0.0f,-0.75f,-0.75f);
-    Static3D[] vertices = new Static3D[4];
-    vertices[0] = new Static3D( 0.5f, 0.0f, 0.0f);
-    vertices[1] = new Static3D(-0.5f, 0.0f, 0.0f);
-    vertices[2] = new Static3D(0.0f, 0.0f,-1.5f);
-    vertices[3] = new Static3D(0.0f,-1.5f, 0.0f);
-
-    roundCorners(mesh,center,vertices,0.06f,0.20f);
-
-    mesh.mergeEffComponents();
-
-    return mesh;
+    return new MeshJoined(meshes);
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  MeshBase createRediCornerMesh()
+  MeshBase createFacesRediCorner()
     {
     final int MESHES=6;
     MeshBase[] meshes = new MeshBase[MESHES];
@@ -1017,37 +508,645 @@ public class CubitFactory
     meshes[5] = meshes[3].copy(true);
     meshes[5].setEffectAssociation(0,32,0);
 
-    MeshBase mesh = new MeshJoined(meshes);
+    return new MeshJoined(meshes);
+    }
 
-    Static3D axisY   = new Static3D(0,1,0);
-    Static3D axisX   = new Static3D(1,0,0);
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsCube()
+    {
+    Static3D axisY   = new Static3D(0,1,0);
+    Static3D axisX   = new Static3D(1,0,0);
+    Static3D center  = new Static3D(0,0,0);
+    Static1D angle90 = new Static1D(90);
+    Static1D angle180= new Static1D(180);
+    Static1D angle270= new Static1D(270);
+
+    VertexEffect[] effect = new VertexEffect[6];
+
+    effect[0] = new VertexEffectMove(new Static3D(0,0,+0.5f));
+    effect[1] = new VertexEffectRotate( angle180, axisX, center );
+    effect[2] = new VertexEffectRotate( angle90 , axisX, center );
+    effect[3] = new VertexEffectRotate( angle270, axisX, center );
+    effect[4] = new VertexEffectRotate( angle270, axisY, center );
+    effect[5] = new VertexEffectRotate( angle90 , axisY, center );
+
+    effect[0].setMeshAssociation(63,-1);  // all 6 sides
+    effect[1].setMeshAssociation(32,-1);  // back
+    effect[2].setMeshAssociation( 8,-1);  // bottom
+    effect[3].setMeshAssociation( 4,-1);  // top
+    effect[4].setMeshAssociation( 2,-1);  // left
+    effect[5].setMeshAssociation( 1,-1);  // right
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsSkewbCorner()
+    {
+    float E = 0.5f;
+
+    Static3D axisX  = new Static3D(1,0,0);
+    Static3D axisY  = new Static3D(0,1,0);
+    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
+    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
+    Static1D angle1 = new Static1D(+90);
+    Static1D angle2 = new Static1D(-90);
+    Static1D angle3 = new Static1D(-15);
+    Static1D angle4 = new Static1D((float)((180.0f/Math.PI)*Math.acos(SQ3/3)));
+    Static1D angle5 = new Static1D(120);
+    Static1D angle6 = new Static1D(240);
+    Static3D center1= new Static3D(0,0,0);
+    Static3D center2= new Static3D(-0.5f,-0.5f,-0.5f);
+    Static3D move1  = new Static3D(-E/4,-E/4,0);
+    Static3D move2  = new Static3D(-0.5f,-0.5f,-0.5f);
+
+    VertexEffect[] effect = new VertexEffect[10];
+
+    effect[0] = new VertexEffectMove(move1);
+    effect[1] = new VertexEffectScale(new Static3D(1,1,-1));
+    effect[2] = new VertexEffectRotate(angle1,axisX,center1);
+    effect[3] = new VertexEffectRotate(angle2,axisY,center1);
+    effect[4] = new VertexEffectMove(move2);
+    effect[5] = new VertexEffectRotate(angle1,axisX,center2);
+    effect[6] = new VertexEffectRotate(angle3,axisY,center2);
+    effect[7] = new VertexEffectRotate(angle4,axis0,center2);
+    effect[8] = new VertexEffectRotate(angle5,axis1,center2);
+    effect[9] = new VertexEffectRotate(angle6,axis1,center2);
+
+    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
+    effect[1].setMeshAssociation( 6,-1);  // meshes 1,2
+    effect[2].setMeshAssociation( 2,-1);  // mesh 1
+    effect[3].setMeshAssociation( 4,-1);  // mesh 2
+    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[7].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[8].setMeshAssociation(16,-1);  // mesh 4
+    effect[9].setMeshAssociation(32,-1);  // mesh 5
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsSkewbFace()
+    {
+    Static3D center = new Static3D(0,0,0);
+    Static3D axisX  = new Static3D(1,0,0);
+    Static3D axisZ  = new Static3D(0,0,1);
+    float angle = -(float)((180.0f/Math.PI)*Math.acos(SQ3/3));
+
+    VertexEffect[] effect = new VertexEffect[6];
+
+    effect[0] = new VertexEffectRotate( new Static1D(angle), axisX, center);
+    effect[1] = new VertexEffectRotate( new Static1D(  135), axisZ, center);
+    effect[2] = new VertexEffectRotate( new Static1D(   45), axisZ, center);
+    effect[3] = new VertexEffectRotate( new Static1D(  -45), axisZ, center);
+    effect[4] = new VertexEffectRotate( new Static1D( -135), axisZ, center);
+    effect[5] = new VertexEffectMove( new Static3D(0,0,-0.5f) );
+
+    effect[0].setMeshAssociation(30,-1);  // meshes 1,2,3,4
+    effect[1].setMeshAssociation( 2,-1);  // mesh 1
+    effect[2].setMeshAssociation( 5,-1);  // meshes 0,2
+    effect[3].setMeshAssociation( 8,-1);  // mesh 3
+    effect[4].setMeshAssociation(16,-1);  // mesh 4
+    effect[5].setMeshAssociation(30,-1);  // meshes 1,2,3,4
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsOcta()
+    {
+    Static1D alpha = new Static1D((float)(-(180/Math.PI)*Math.asin(SQ3/3)));
+    Static1D angle1= new Static1D( 90);
+    Static1D angle2= new Static1D(180);
+    Static1D angle3= new Static1D(270);
+    Static3D move1 = new Static3D(0,SQ2/2-SQ3/3,0);
+    Static3D axisX = new Static3D(1,0,0);
+    Static3D axisY = new Static3D(0,1,0);
+    Static3D cent0 = new Static3D(0,0,0);
+    Static3D cent1 = new Static3D(0,SQ2/2,0);
+    Static3D flipY = new Static3D( 1,-1, 1);
+
+    VertexEffect[] effect = new VertexEffect[6];
+
+    effect[0] = new VertexEffectMove(move1);
+    effect[1] = new VertexEffectRotate(alpha , axisX, cent1);
+    effect[2] = new VertexEffectRotate(angle1, axisY, cent0);
+    effect[3] = new VertexEffectRotate(angle2, axisY, cent0);
+    effect[4] = new VertexEffectRotate(angle3, axisY, cent0);
+    effect[5] = new VertexEffectScale(flipY);
+
+    effect[2].setMeshAssociation ( 34,-1); // apply to meshes 1 & 5
+    effect[3].setMeshAssociation ( 68,-1); // apply to meshes 2 & 6
+    effect[4].setMeshAssociation (136,-1); // apply to meshes 3 & 7
+    effect[5].setMeshAssociation (240,-1); // apply to meshes 4,5,6,7
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsTetra()
+    {
+    Static3D flipZ = new Static3D( 1, 1,-1);
+
+    Static1D alpha = new Static1D((float)(-(180/Math.PI)*Math.asin(SQ3/3)));
+    Static1D angle1= new Static1D( 90);
+    Static1D angle2= new Static1D(180);
+    Static3D move1 = new Static3D(0,SQ2/4-SQ3/6,0);
+
+    Static3D axisX = new Static3D(1,0,0);
+    Static3D axisY = new Static3D(0,1,0);
+    Static3D axisZ = new Static3D(0,0,1);
+
+    Static3D cent0 = new Static3D(0,0,0);
+    Static3D cent1 = new Static3D(0,SQ2/4,0);
+
+    VertexEffect[] effect = new VertexEffect[6];
+
+    effect[0] = new VertexEffectRotate(angle2, axisZ, cent0);
+    effect[1] = new VertexEffectMove(move1);
+    effect[2] = new VertexEffectRotate(alpha , axisX, cent1);
+    effect[3] = new VertexEffectScale(flipZ);
+    effect[4] = new VertexEffectRotate(angle1, axisY, cent0);
+    effect[5] = new VertexEffectRotate(angle2, axisZ, cent0);
+
+    effect[0].setMeshAssociation(15,-1); // meshes 0,1,2,3
+    effect[1].setMeshAssociation(15,-1); // meshes 0,1,2,3
+    effect[2].setMeshAssociation(15,-1); // meshes 0,1,2,3
+    effect[3].setMeshAssociation(10,-1); // meshes 1 & 3
+    effect[4].setMeshAssociation(12,-1); // meshes 2 & 3
+    effect[5].setMeshAssociation(12,-1); // meshes 2 & 3
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsDino()
+    {
+    float E = 0.5f*SQ2;
+    float F = 0.5f;
+    final float ANGLE = (float)((180/Math.PI)*(Math.atan(SQ2)));
+
+    Static1D angle1 = new Static1D(+ANGLE);
+    Static1D angle2 = new Static1D(-ANGLE);
+    Static3D axisX  = new Static3D(1,0,0);
+    Static3D axisY  = new Static3D(0,1,0);
+    Static3D axisZ  = new Static3D(0,-1,1);
+    Static3D center0= new Static3D(0,0,0);
+    Static3D center1= new Static3D(0,-3*F,0);
+
+    VertexEffect[] effect = new VertexEffect[10];
+
+    effect[0] = new VertexEffectScale ( new Static3D(3,3,3) );
+    effect[1] = new VertexEffectMove  ( new Static3D(0,-F,0) );
+    effect[2] = new VertexEffectRotate( new Static1D(90), axisX, center0 );
+    effect[3] = new VertexEffectScale ( new Static3D(1,-1,1) );
+    effect[4] = new VertexEffectMove  ( new Static3D(3*E/2,E*(SQ3/2)-3*F,0) );
+    effect[5] = new VertexEffectRotate( new Static1D(+90), axisY, center1 );
+    effect[6] = new VertexEffectScale ( new Static3D(-1,1,1) );
+    effect[7] = new VertexEffectRotate( new Static1D( 45), axisX, center1 );
+    effect[8] = new VertexEffectRotate( angle1           , axisZ, center1 );
+    effect[9] = new VertexEffectRotate( angle2           , axisZ, center1 );
+
+    effect[0].setMeshAssociation(15,-1);  // apply to meshes 0,1,2,3
+    effect[1].setMeshAssociation( 3,-1);  // apply to meshes 0,1
+    effect[2].setMeshAssociation( 2,-1);  // apply to mesh 1
+    effect[3].setMeshAssociation( 2,-1);  // apply to mesh 0
+    effect[4].setMeshAssociation(12,-1);  // apply to meshes 2,3
+    effect[5].setMeshAssociation(12,-1);  // apply to meshes 2,3
+    effect[6].setMeshAssociation( 8,-1);  // apply to mesh 3
+    effect[7].setMeshAssociation(12,-1);  // apply to meshes 2,3
+    effect[8].setMeshAssociation( 4,-1);  // apply to mesh 2
+    effect[9].setMeshAssociation( 8,-1);  // apply to mesh 3
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsHelicopterCorner()
+    {
+    float E = 0.5f;
+
+    Static3D axisX  = new Static3D(1,0,0);
+    Static3D axisY  = new Static3D(0,1,0);
+    Static3D axis0  = new Static3D(-SQ2/2,0,SQ2/2);
+    Static3D axis1  = new Static3D(+SQ3/3,+SQ3/3,+SQ3/3);
+    Static1D angle1 = new Static1D(+90);
+    Static1D angle2 = new Static1D(-90);
+    Static1D angle3 = new Static1D(-135);
+    Static1D angle4 = new Static1D(90);
+    Static1D angle5 = new Static1D(120);
+    Static1D angle6 = new Static1D(240);
+    Static3D center1= new Static3D(0,0,0);
+    Static3D center2= new Static3D(-0.25f,-0.25f,-0.25f);
+    Static3D move1  = new Static3D(-E/4,-E/4,0);
+    Static3D move2  = new Static3D(-0.25f,(-1.0f/6)-0.25f,-0.25f);
+
+    VertexEffect[] effect = new VertexEffect[10];
+
+    effect[0] = new VertexEffectMove(move1);
+    effect[1] = new VertexEffectScale(new Static3D(1,1,-1));
+    effect[2] = new VertexEffectRotate(angle1,axisX,center1);
+    effect[3] = new VertexEffectRotate(angle2,axisY,center1);
+    effect[4] = new VertexEffectMove(move2);
+    effect[5] = new VertexEffectRotate(angle1,axisX,center2);
+    effect[6] = new VertexEffectRotate(angle3,axisY,center2);
+    effect[7] = new VertexEffectRotate(angle4,axis0,center2);
+    effect[8] = new VertexEffectRotate(angle5,axis1,center2);
+    effect[9] = new VertexEffectRotate(angle6,axis1,center2);
+
+    effect[0].setMeshAssociation( 7,-1);  // meshes 0,1,2
+    effect[1].setMeshAssociation( 6,-1);  // meshes 1,2
+    effect[2].setMeshAssociation( 2,-1);  // mesh 1
+    effect[3].setMeshAssociation( 4,-1);  // mesh 2
+    effect[4].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[5].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[6].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[7].setMeshAssociation(56,-1);  // meshes 3,4,5
+    effect[8].setMeshAssociation(16,-1);  // mesh 4
+    effect[9].setMeshAssociation(32,-1);  // mesh 5
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsHelicopterFace()
+    {
+    float E = 0.5f;
+    float F = SQ2/4;
+
+    Static3D move0  = new Static3D(-E/4, -E/4, 0);
+    Static3D move1  = new Static3D(-(SQ2/24)-E/2, -(SQ2/24)-E/2, 0);
+    Static3D move2  = new Static3D(-E/2, F/3, 0);
+    Static3D move3  = new Static3D(+E/2, F/3, 0);
+    Static3D move4  = new Static3D(+E/3,+E/3, 0);
+    Static1D angle1 = new Static1D(135);
+    Static1D angle2 = new Static1D(90);
+    Static1D angle3 = new Static1D(-90);
+    Static1D angle4 = new Static1D(-135);
+    Static3D axisX  = new Static3D(1,0,0);
+    Static3D axisY  = new Static3D(0,1,0);
+    Static3D axisZ  = new Static3D(0,0,1);
+    Static3D axis1  = new Static3D(1,-1,0);
+    Static3D center = new Static3D(0,0,0);
+    Static3D center1= new Static3D(-E/2,-E/2,0);
+
+    VertexEffect[] effect = new VertexEffect[10];
+
+    effect[0] = new VertexEffectMove(move0);
+    effect[1] = new VertexEffectRotate(angle1, axisZ, center);
+    effect[2] = new VertexEffectMove(move1);
+    effect[3] = new VertexEffectRotate(angle2, axis1, center1);
+    effect[4] = new VertexEffectMove(move2);
+    effect[5] = new VertexEffectMove(move3);
+    effect[6] = new VertexEffectRotate(angle3, axisZ, center);
+    effect[7] = new VertexEffectRotate(angle4, axisX, center);
+    effect[8] = new VertexEffectRotate(angle1, axisY, center);
+    effect[9] = new VertexEffectMove(move4);
+
+    effect[0].setMeshAssociation( 1,-1);  // mesh 0
+    effect[1].setMeshAssociation( 2,-1);  // mesh 1
+    effect[2].setMeshAssociation( 2,-1);  // mesh 1
+    effect[3].setMeshAssociation( 2,-1);  // mesh 1
+    effect[4].setMeshAssociation( 4,-1);  // mesh 2
+    effect[5].setMeshAssociation( 8,-1);  // mesh 3
+    effect[6].setMeshAssociation( 8,-1);  // mesh 3
+    effect[7].setMeshAssociation( 4,-1);  // mesh 2
+    effect[8].setMeshAssociation( 8,-1);  // mesh 3
+    effect[9].setMeshAssociation(15,-1);  // meshes 0,1,2,3
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsRediEdge()
+    {
+    Static3D move0 = new Static3D(0.0f, -0.5f, 0.0f);
+    Static3D move1 = new Static3D(0.25f, -0.25f, 0.0f);
+    Static3D move2 = new Static3D(0.5f, 0.0f, 0.0f);
+    Static3D move3 = new Static3D(0.0f, (SQ3-6)/8, (SQ3-6)/8);
+    Static3D flipZ = new Static3D(1,1,-1);
+    Static3D flipX = new Static3D(-1,1,1);
+    Static3D scale = new Static3D(2,2,2);
+    Static3D cent0 = new Static3D(0,0, 0);
+    Static3D cent1 = new Static3D(0,0, -1.5f);
+    Static3D axisX = new Static3D(1,0, 0);
+    Static3D axisY = new Static3D(0,1, 0);
+    Static3D axis  = new Static3D(0,SQ2/2,-SQ2/2);
+    Static1D angle1= new Static1D(90);
+    Static1D angle2= new Static1D(45);
+    Static1D angle3= new Static1D( (float)(180/Math.PI*Math.acos(SQ3/3)) );
+
+    VertexEffect[] effect = new VertexEffect[12];
+
+    effect[0] = new VertexEffectScale(scale);
+    effect[1] = new VertexEffectMove(move0);
+    effect[2] = new VertexEffectScale(flipZ);
+    effect[3] = new VertexEffectRotate(angle1,axisX,cent0);
+    effect[4] = new VertexEffectMove(move1);
+    effect[5] = new VertexEffectRotate(angle1,axisY,cent0);
+    effect[6] = new VertexEffectMove(move2);
+    effect[7] = new VertexEffectScale(flipX);
+    effect[8] = new VertexEffectRotate(angle2,axisX,cent0);
+    effect[9] = new VertexEffectMove(move3);
+    effect[10]= new VertexEffectRotate(angle3,axis ,cent1);
+    effect[11]= new VertexEffectScale(flipX);
+
+    effect[0].setMeshAssociation(63,-1);  // meshes 0,1,2,3,4,5
+    effect[1].setMeshAssociation( 3,-1);  // meshes 0,1
+    effect[2].setMeshAssociation( 2,-1);  // mesh 1
+    effect[3].setMeshAssociation( 2,-1);  // mesh 1
+    effect[4].setMeshAssociation(12,-1);  // meshes 2,3
+    effect[5].setMeshAssociation(60,-1);  // meshes 2,3,4,5
+    effect[6].setMeshAssociation(12,-1);  // meshes 2,3
+    effect[7].setMeshAssociation( 8,-1);  // mesh 3
+    effect[8].setMeshAssociation(48,-1);  // meshes 4,5
+    effect[9].setMeshAssociation(48,-1);  // meshes 4,5
+    effect[10].setMeshAssociation(48,-1); // meshes 4,5
+    effect[11].setMeshAssociation(32,-1); // mesh 5
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  VertexEffect[] createVertexEffectsRediCorner()
+    {
+    Static3D axisY   = new Static3D(0,1,0);
+    Static3D axisX   = new Static3D(1,0,0);
     Static3D axisZ   = new Static3D(0,0,1);
     Static3D center  = new Static3D(0,0,0);
     Static1D angle90 = new Static1D(90);
     Static1D angle270= new Static1D(270);
     Static1D angle45 = new Static1D(-45);
 
-    VertexEffect effect0 = new VertexEffectMove(new Static3D(0,0,+0.5f));
-    VertexEffect effect1 = new VertexEffectRotate( angle270, axisX, center );
-    VertexEffect effect2 = new VertexEffectRotate( angle90 , axisY, center );
-    VertexEffect effect3 = new VertexEffectRotate( angle45 , axisX, center );
-    VertexEffect effect4 = new VertexEffectRotate( angle90 , axisY, center );
-    VertexEffect effect5 = new VertexEffectRotate( angle270, axisZ, center );
-
-    effect0.setMeshAssociation( 7,-1);  // 0,1,2
-    effect1.setMeshAssociation( 2,-1);  // 1
-    effect2.setMeshAssociation( 4,-1);  // 2
-    effect3.setMeshAssociation(56,-1);  // 3
-    effect4.setMeshAssociation(16,-1);  // 4
-    effect5.setMeshAssociation(32,-1);  // 5
-
-    mesh.apply(effect0);
-    mesh.apply(effect1);
-    mesh.apply(effect2);
-    mesh.apply(effect3);
-    mesh.apply(effect4);
-    mesh.apply(effect5);
+    VertexEffect[] effect = new VertexEffect[6];
+
+    effect[0] = new VertexEffectMove(new Static3D(0,0,+0.5f));
+    effect[1] = new VertexEffectRotate( angle270, axisX, center );
+    effect[2] = new VertexEffectRotate( angle90 , axisY, center );
+    effect[3] = new VertexEffectRotate( angle45 , axisX, center );
+    effect[4] = new VertexEffectRotate( angle90 , axisY, center );
+    effect[5] = new VertexEffectRotate( angle270, axisZ, center );
+
+    effect[0].setMeshAssociation( 7,-1);  // 0,1,2
+    effect[1].setMeshAssociation( 2,-1);  // 1
+    effect[2].setMeshAssociation( 4,-1);  // 2
+    effect[3].setMeshAssociation(56,-1);  // 3
+    effect[4].setMeshAssociation(16,-1);  // 4
+    effect[5].setMeshAssociation(32,-1);  // 5
+
+    return effect;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OBJECTS
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// CUBE
+
+  MeshBase createCubeMesh(int index)
+    {
+    MeshBase mesh = createFacesCube(index);
+    VertexEffect[] effects = createVertexEffectsCube();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    Static3D roundingCenter  = new Static3D(0,0,0);
+    Static3D[] vertices = new Static3D[8];
+    vertices[0] = new Static3D(+0.5f,+0.5f,+0.5f);
+    vertices[1] = new Static3D(+0.5f,+0.5f,-0.5f);
+    vertices[2] = new Static3D(+0.5f,-0.5f,+0.5f);
+    vertices[3] = new Static3D(+0.5f,-0.5f,-0.5f);
+    vertices[4] = new Static3D(-0.5f,+0.5f,+0.5f);
+    vertices[5] = new Static3D(-0.5f,+0.5f,-0.5f);
+    vertices[6] = new Static3D(-0.5f,-0.5f,+0.5f);
+    vertices[7] = new Static3D(-0.5f,-0.5f,-0.5f);
+
+    roundCorners(mesh,roundingCenter,vertices,0.06f,0.12f);
+
+    mesh.mergeEffComponents();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// SKEWB
+
+  MeshBase createSkewbCornerMesh()
+    {
+    MeshBase mesh = createFacesSkewbCorner();
+    VertexEffect[] effects = createVertexEffectsSkewbCorner();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    float E = 0.5f;
+    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
+
+    Static3D[] verticesType1 = new Static3D[1];
+    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
+    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
+
+    Static3D[] verticesType2 = new Static3D[3];
+    verticesType2[0] = new Static3D(-E, 0, 0);
+    verticesType2[1] = new Static3D( 0,-E, 0);
+    verticesType2[2] = new Static3D( 0, 0,-E);
+    roundCorners(mesh,roundingCenter,verticesType2,0.08f,0.20f);
+
+    mesh.mergeEffComponents();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createSkewbFaceMesh()
+    {
+    MeshBase mesh = createFacesSkewbFace();
+    VertexEffect[] effects = createVertexEffectsSkewbFace();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    Static3D roundingCenter = new Static3D(0,0,-0.2f);
+    float E = SQ2/4;
+    Static3D[] vertices = new Static3D[4];
+    vertices[0] = new Static3D(-E*SQ2,      0, 0);
+    vertices[1] = new Static3D(+E*SQ2,      0, 0);
+    vertices[2] = new Static3D(     0, -E*SQ2, 0);
+    vertices[3] = new Static3D(     0, +E*SQ2, 0);
+    roundCorners(mesh,roundingCenter,vertices,0.10f,0.10f);
+
+    mesh.mergeEffComponents();
+    mesh.addEmptyTexComponent();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// SKEWB DIAMOND / PYRAMINX
+
+  MeshBase createOctaMesh()
+    {
+    MeshBase mesh = createFacesOcta();
+    VertexEffect[] effects = createVertexEffectsOcta();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    Static3D roundingCenter = new Static3D(0,0,0);
+    Static3D[] vertices = new Static3D[6];
+    vertices[0] = new Static3D(    0, SQ2/2,    0 );
+    vertices[1] = new Static3D( 0.5f,     0, 0.5f );
+    vertices[2] = new Static3D(-0.5f,     0, 0.5f );
+    vertices[3] = new Static3D(    0,-SQ2/2,    0 );
+    vertices[4] = new Static3D(-0.5f,     0,-0.5f );
+    vertices[5] = new Static3D( 0.5f,     0,-0.5f );
+
+    roundCorners(mesh,roundingCenter,vertices,0.06f,0.20f);
+
+    mesh.mergeEffComponents();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createTetraMesh()
+    {
+    MeshBase mesh = createFacesTetra();
+    VertexEffect[] effects = createVertexEffectsTetra();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    Static3D roundingCenter = new Static3D(0,0,0);
+    Static3D[] verticesRound = new Static3D[4];
+    verticesRound[0] = new Static3D(-0.5f,+SQ2/4,   0 );
+    verticesRound[1] = new Static3D(+0.5f,+SQ2/4,   0 );
+    verticesRound[2] = new Static3D(    0,-SQ2/4,+0.5f);
+    verticesRound[3] = new Static3D(    0,-SQ2/4,-0.5f);
+    roundCorners(mesh,roundingCenter,verticesRound,0.08f,0.15f);
+
+    mesh.mergeEffComponents();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+
+    return mesh;
+    }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// DINO
+
+  MeshBase createDinoMesh()
+    {
+    MeshBase mesh = createFacesDino();
+    VertexEffect[] effects = createVertexEffectsDino();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    float F = 0.5f;
+    Static3D roundingCenter = new Static3D(0.0f, -1.5f*F, -1.5f*F);
+    Static3D[] verticesRound = new Static3D[4];
+    verticesRound[0] = new Static3D(     0,-3*F,    0 );
+    verticesRound[1] = new Static3D(     0,   0, -3*F );
+    verticesRound[2] = new Static3D(  -3*F,   0,    0 );
+    verticesRound[3] = new Static3D(  +3*F,   0,    0 );
+    roundCorners(mesh,roundingCenter,verticesRound,0.10f,0.40f);
+
+    mesh.mergeEffComponents();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Helicopter
+
+  MeshBase createHelicopterCornerMesh()
+    {
+    MeshBase mesh = createFacesHelicopterCorner();
+    VertexEffect[] effects = createVertexEffectsHelicopterCorner();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    float E = 0.5f;
+    Static3D roundingCenter = new Static3D(-E/2,-E/2,-E/2);
+
+    Static3D[] verticesType1 = new Static3D[1];
+    verticesType1[0] = new Static3D(0.0f,0.0f,0.0f);
+    roundCorners(mesh,roundingCenter,verticesType1,0.08f,0.15f);
+
+    Static3D[] verticesType2 = new Static3D[3];
+    verticesType2[0] = new Static3D(-E, 0, 0);
+    verticesType2[1] = new Static3D( 0,-E, 0);
+    verticesType2[2] = new Static3D( 0, 0,-E);
+    roundCorners(mesh,roundingCenter,verticesType2,0.10f,0.20f);
+
+    mesh.mergeEffComponents();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createHelicopterFaceMesh()
+    {
+    MeshBase mesh = createFacesHelicopterFace();
+    VertexEffect[] effects = createVertexEffectsHelicopterFace();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    float E = 0.5f;
+    Static3D roundingCenter = new Static3D(-E/2 + E/3,-E/2 + E/3,-E/2);
+
+    Static3D[] verticesType1 = new Static3D[1];
+    verticesType1[0] = new Static3D(E/3,E/3,0.0f);
+    roundCorners(mesh,roundingCenter,verticesType1,0.06f,0.15f);
+
+    Static3D[] verticesType2 = new Static3D[2];
+    verticesType2[0] = new Static3D(-E+E/3, E/3  , 0);
+    verticesType2[1] = new Static3D( E/3  ,-E+E/3, 0);
+    roundCorners(mesh,roundingCenter,verticesType2,0.10f,0.20f);
+
+    mesh.mergeEffComponents();
+    mesh.addEmptyTexComponent();
+    mesh.addEmptyTexComponent();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Redi cube
+
+  MeshBase createRediEdgeMesh()
+    {
+    MeshBase mesh = createFacesRediEdge();
+    VertexEffect[] effects = createVertexEffectsRediEdge();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    Static3D center = new Static3D(0.0f,-0.75f,-0.75f);
+    Static3D[] vertices = new Static3D[4];
+    vertices[0] = new Static3D( 0.5f, 0.0f, 0.0f);
+    vertices[1] = new Static3D(-0.5f, 0.0f, 0.0f);
+    vertices[2] = new Static3D(0.0f, 0.0f,-1.5f);
+    vertices[3] = new Static3D(0.0f,-1.5f, 0.0f);
+
+    roundCorners(mesh,center,vertices,0.06f,0.20f);
+
+    mesh.mergeEffComponents();
+
+    return mesh;
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  MeshBase createRediCornerMesh()
+    {
+    MeshBase mesh = createFacesRediCorner();
+    VertexEffect[] effects = createVertexEffectsRediCorner();
+    for( VertexEffect effect : effects ) mesh.apply(effect);
+
+    Static3D center = new Static3D(0,0,0);
     Static3D[] vertices = new Static3D[8];
     vertices[0] = new Static3D(+0.5f,+0.5f,+0.5f);
     vertices[1] = new Static3D(+0.5f,+0.5f,-0.5f);
