From c3c47406ac43dafd51e6ad1d7b92a794bd69b7d6 Mon Sep 17 00:00:00 2001
From: Normand Briere <nbriere@noware.ca>
Date: Fri, 27 Sep 2019 20:03:29 -0400
Subject: [PATCH] Fix/patch click flicking.

---
 BoundaryRep.java |  802 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 602 insertions(+), 200 deletions(-)

diff --git a/BoundaryRep.java b/BoundaryRep.java
index 9cf899c..6fecd44 100644
--- a/BoundaryRep.java
+++ b/BoundaryRep.java
@@ -7,7 +7,8 @@
 
 class BoundaryRep implements java.io.Serializable
 {
-    static final long serialVersionUID = -4852664309425035321L;
+    static final long serialVersionUID = // VERY old 2008 -5762968998168738314L;
+                                        -4852664309425035321L;
 
     transient int displaylist = 0;
     
@@ -15,7 +16,7 @@
     {
         this(0, 0);
     }
-    
+
     void SaveSupports()
     {
         transientsupport = support;
@@ -161,6 +162,7 @@
                 || FaceCount() != other.FaceCount()
                 || !(indices == null ^ other.indices != null)) // july 2014
         {
+            // The meshes have different structures.
             //new Exception().printStackTrace();
             trimmed = other.trimmed;
             stripified = other.stripified;
@@ -172,16 +174,16 @@
             bufV = other.bufV;
             bufF = other.bufF;
 
-            positions = (float[]) GrafreeD.clone(other.positions);
-            normals = (float[]) GrafreeD.clone(other.normals);
-            colors = (float[]) GrafreeD.clone(other.colors);
-            uvmap = (float[]) GrafreeD.clone(other.uvmap);
-            triangles = (int[]) GrafreeD.clone(other.triangles);
+            positions = (float[]) Grafreed.clone(other.positions);
+            normals = (float[]) Grafreed.clone(other.normals);
+            colors = (float[]) Grafreed.clone(other.colors);
+            uvmap = (float[]) Grafreed.clone(other.uvmap);
+            triangles = (int[]) Grafreed.clone(other.triangles);
             
-            indices = (int[]) GrafreeD.clone(other.indices);
+            indices = (int[]) Grafreed.clone(other.indices);
 
-            vertices = (Vector<Vertex>) GrafreeD.clone(other.vertices);
-            faces = (Vector<Face>) GrafreeD.clone(other.faces);
+            vertices = (Vector<Vertex>) Grafreed.clone(other.vertices);
+            faces = (Vector<Face>) Grafreed.clone(other.faces);
         }
         else
         {
@@ -239,9 +241,16 @@
         }
     }
 
-    Support[] InitConnections(BoundaryRep other)
+    transient Support[] cachesupports = null;
+    
+    Support[] InitConnections()
     {
-        int n = other.startvertices.length-1;
+        if (cachesupports != null)
+        {
+            return cachesupports;
+        }
+        
+        int n = this.startvertices.length-1;
         
         Support[] supports = new Support[n];
         
@@ -253,38 +262,60 @@
         
         for (int object=1; object<=n; object++)
         {
-            int start = other.startvertices[object-1];
-            int end = other.startvertices[object];
+            int start = this.startvertices[object-1];
+            int end = this.startvertices[object];
 
             if (start == end)
                 continue; // ??
             
+            /**
+        Vertex v2 = vertextemp;
+        v2.x = averagepoints[object*3];
+        v2.y = averagepoints[object*3+1];
+        v2.z = averagepoints[object*3+2];
+        
+        //v2.set(GetVertex(this.startvertices[subsupport]));
+        
+        // projected point
+        Vertex v3 = vertextemp2;
+        //GetVertex(this.startvertices[subsupport]);
+        v3.x = extremepoints[object*3];
+        v3.y = extremepoints[object*3+1];
+        v3.z = extremepoints[object*3+2];
+
+        vect3.set(v3); // "X" axis apex
+        vect3.sub(v2); // origin (center)
+        vect3.normalize();
+            /**/
+            
             int linkcount = 0;
 
             int objectinlist = -1;
+            
+            Support subsupport = supports[object-1];
 
             for (int object2=1; object2<=n; object2++)
             {
                 for (int i = start; i < end; i++)
                 {
-                    Vertex v = other.GetVertex(i);
+                    Vertex v = this.GetVertex(i);
 
-                    // 
-                    if (other.Contains(v, object2))
+                    // Check if v is close enough from any vertex of the given subobject.
+                    if (this.Contains(v, object2))
                     {
-                        if (linkcount == supports[object-1].links.length)
+                        if (linkcount == subsupport.links.length)
                             break;
 
                         if (object2 == object)
                             objectinlist = linkcount;
                         
-                        supports[object-1].links[linkcount++] = object2;
+                        subsupport.links[linkcount++] = object2;
                         break;
                     }
                 }
             }
                 
-            supports[object-1].links[linkcount] = -1;
+            subsupport.links[linkcount] = -1;
 
             if (objectinlist == -1)
                 assert(objectinlist != -1);
@@ -293,9 +324,9 @@
 //                assert(linkcount > 1);
 
             // show main support as blue
-            int first = supports[object-1].links[0];
-            supports[object-1].links[0] = supports[object-1].links[objectinlist];
-            supports[object-1].links[objectinlist] = first;
+            int first = subsupport.links[0];
+            subsupport.links[0] = subsupport.links[objectinlist];
+            subsupport.links[objectinlist] = first;
         }
 
         for (int loop = 0; --loop>=0;)
@@ -353,7 +384,7 @@
             supports = supports2;
         }
         
-        return supports;
+        return cachesupports = supports;
     }
     
     double Distance2(Vertex v, Vertex v2, double dist2beat, double[][] toRoot, int k)
@@ -500,7 +531,7 @@
     static Vertex vertextemp = new Vertex(true);
     static Vertex vertextemp2 = new Vertex(true);
     
-    static double SEUIL = 0.1f; // 0.1 for rag doll; 0.07;
+    static double SEUIL = 0.025f; // 0.1 for rag doll; 0.07;
         
     // Compute weight of point w/r to this
     float ComputeWeight(Vertex v, double[][] toRoot, int k)
@@ -598,7 +629,7 @@
 //                ;
         //
 
-        supportsize = supportsizes[subsupport];
+        supportsize = supportminsize[subsupport];
         
         double K = supportsize / distmax;
         
@@ -650,11 +681,13 @@
     //    if (supportsize * fadefactor > 1)
     //        return 1;
         
-        return supportsize * fadefactor;
+        return //supportsize *
+                supportsize * fadefactor;
     }
     
     void RecomputeBasis(BoundaryRep other, double[][] toRoot, Vertex v)
     {
+        CameraPane.CreateSelectedPoint();
         CameraPane.selectedpoint.
             getAverage(cStatic.point1, true);
 
@@ -790,7 +823,7 @@
             v.weights[k] = other.ComputeWeight(v, toRoot, k); // (float)(supportsize * normalweight * nz / Math.pow(tx*tx+ty*ty+tz*tz, 1));
             v.totalweight += v.weights[k];
             
-            if (CameraPane.CROWD)
+            if (Globals.CROWD)
             {
       //          System.out.print("weight = " + v.weights[k]);
       //          System.out.println("; totalweight = " + v.totalweight);
@@ -952,7 +985,7 @@
         
         // sept 2017 SEUIL = 0.1; // aout 2013
         
-        supports = InitConnections(other);
+        supports = other.InitConnections();
         
         other.supports = supports; // should be the other way around...
         
@@ -972,6 +1005,7 @@
             
             v.closestsupport = -1;
             
+        CameraPane.CreateSelectedPoint();
         CameraPane.selectedpoint.
             getAverage(cStatic.point1, true);
 
@@ -1230,6 +1264,7 @@
         for (int wi = v0.weights.length; --wi>=0;)
             v[wi] = 0;
             
+        CameraPane.CreateSelectedPoint();
         CameraPane.selectedpoint.
             getAverage(cStatic.point1, true);
 
@@ -1367,6 +1402,7 @@
         v0.x = v0.y = v0.z = 0;
         v0.norm.x = v0.norm.y = v0.norm.z = 0;
             
+        CameraPane.CreateSelectedPoint();
         CameraPane.selectedpoint.
             getAverage(cStatic.point1, true);
 
@@ -1518,7 +1554,7 @@
             InitFaceIndices();
         }
         
-        BoundaryRep rep = (BoundaryRep) GrafreeD.clone(this);
+        BoundaryRep rep = (BoundaryRep) Grafreed.clone(this);
         //float[] v = new float[100];
         
         for (int loops=1; --loops>=0;)
@@ -1548,7 +1584,7 @@
             InitFaceIndices();
         }
         
-        BoundaryRep rep = (BoundaryRep) GrafreeD.clone(this);
+        BoundaryRep rep = (BoundaryRep) Grafreed.clone(this);
         //float[] v = new float[100];
         
         for (int loops=10; --loops>=0;)
@@ -1895,7 +1931,7 @@
             return;
         }
         
-    //    System.exit(0);
+        // System.exit(0);
         
         cVector vect = new cVector();
         cVector normal = new cVector();
@@ -1966,7 +2002,10 @@
                 if (v.vertexlinks == null)
                     continue;
                 
-                if (v.weights != null && v.weights[j] == 0) // < 0.01 * v.totalweight) // == 0)
+                // Warning: faster but dangerous
+                if (v.weights != null && v.weights[j]
+                         == 0)
+                        //< 0.001 * v.totalweight)
                 {
                     //testweight += v.weights[j-1];
                     continue;
@@ -2247,6 +2286,8 @@
     
     transient int lastsoundtime;
     
+    transient boolean once = false;
+    
     void setMasterThis0(BoundaryRep other, double[][] toRoot, boolean smooth, boolean marked)
     {
         if (LA.isIdentity(toRoot))
@@ -2302,7 +2343,11 @@
 
             if (v.totalweight == 0)
             {
-                System.err.println("v.totalweight == 0! --> " + this + " : " + other);
+                if (!once)
+                {
+                    System.err.println("v.totalweight == 0! --> " + this + " : " + other);
+                    once = true;
+                }
                 continue;
             }
                 
@@ -2661,18 +2706,18 @@
         if (false) // slow && stepout && onein)
         {
             // sound
-            cVector eye = CameraPane.theRenderer.eyeCamera.location;
+            cVector eye = Globals.theRenderer.EyeCamera().location;
 
             Vertex v = GetVertex(0);
 
             tmp.set(v);
             tmp.sub(eye);
 
-            if (CameraPane.framecount - lastsoundtime > 30) // 0.25 secs
+            if (Globals.framecount - lastsoundtime > 30) // 0.25 secs
             {
-                GrafreeD.wav.play((Math.random()+0.5)/Math.max(tmp.length2(),0.2)); //, 1);
+                Grafreed.wav.play((Math.random()+0.5)/Math.max(tmp.length2(),0.2)); //, 1);
 
-                lastsoundtime = CameraPane.framecount;
+                lastsoundtime = Globals.framecount;
             }
             
             stepout = false;
@@ -3098,6 +3143,7 @@
 //    
 //    transient VertexCompare[] vertexcompare = null;
     
+    // Check if v0 is close enough from any vertex of the given subobject of this.
     boolean Contains(Vertex v0, int object)
     {
         int start = startvertices[object-1];
@@ -3155,7 +3201,27 @@
      */
     }
 
-    void GenUV()
+    void UnfoldUV()
+    {
+            for (int i = 0; i < VertexCount(); i++)
+            {
+                Vertex v = GetVertex(i);
+                
+                v.x = v.s;
+                v.y = v.t;
+                v.z = 0;
+                
+                v.norm.x = 0;
+                v.norm.y = 0;
+                v.norm.z = 1;
+                
+                SetVertex(v, i);
+            }
+    }
+    
+    float power = 2;
+    
+    void GenUV() // float power)
     {
         Trim();
         
@@ -3219,6 +3285,125 @@
                 y -= 0.5;
                 z -= 0.5;
                 
+                double ax = Math.abs(x);
+                double ay = Math.abs(y);
+                double max = ax;
+                if (max < ay)
+                {
+                    max = ay;
+                }
+                
+                if (max == 0)
+                {
+                        uvmap[i2] = 0.5f;
+                        uvmap[i2+1] = 0.5f;
+                        continue;
+                }
+                
+                x /= max;
+                y /= max;
+
+                double angle = Math.acos(Math.abs(z*2));
+                
+                double k = angle / Math.PI * 2;
+                
+                assert(k >= 0);
+                
+                // k == 0 => uv = 0 (center)
+                // k == 1 => uv = -1,1 (border)
+                
+                if (i == 0)
+                        System.out.println("power = " + power);
+                
+                double length1 = (ax+ay)/max;
+                double length2 = Math.sqrt(ax*ax + ay*ay) / max;
+
+                double t = k;
+                
+                t = Math.pow(t, 3);
+                
+                // Interpolate between k/length2 (center) and k (border)
+                if (length2 > 0)
+                        k *= (1 - t) / length2 + t;
+                
+                double u = k*x;
+                double v = k*y;
+
+                u /= 2;
+                v /= 2;
+                u += 0.5;
+                v += 0.5;
+                
+                uvmap[i2] = (float) u;
+                uvmap[i2+1] = (float) v;
+            }
+    }
+        
+    void GenUVold(float power)
+    {
+        Trim();
+        
+        cVector boxcenter = null;
+          cVector minima, maxima;
+            minima = new cVector();
+            maxima = new cVector();
+            minima.x = minima.y = minima.z = Double.MAX_VALUE;
+            maxima.x = maxima.y = maxima.z = -Double.MAX_VALUE;
+            for (int i = 0; i < VertexCount(); i++)
+            {
+                Vertex v = GetVertex(i);
+
+                if (minima.x > v.x)
+                {
+                    minima.x = v.x;
+                }
+                if (minima.y > v.y)
+                {
+                    minima.y = v.y;
+                }
+                if (minima.z > v.z)
+                {
+                    minima.z = v.z;
+                }
+
+                if (maxima.x < v.x)
+                {
+                    maxima.x = v.x;
+                }
+                if (maxima.y < v.y)
+                {
+                    maxima.y = v.y;
+                }
+                if (maxima.z < v.z)
+                {
+                    maxima.z = v.z;
+                }
+            }
+
+            boxcenter = new cVector((maxima.x + minima.x) / 2, (maxima.y + minima.y) / 2, (maxima.z + minima.z) / 2);
+            int i2 = 0, i3 = 0;
+            for (int i = 0; i < positions.length/3; i++, i3 += 3, i2 += 2)
+            {
+//                //uvmap[i2] = (float) normals[i3]*0.5f + 0.5f; // v.x;
+//                //uvmap[i2 + 1] = (float) normals[i3+1]*0.5f + 0.5f; //z;
+//                uvmap[i2] = (float) (positions[i3] - boxcenter.x);
+//                uvmap[i2 + 1] = (float) (positions[i3+2] - boxcenter.z);
+//                uvmap[i2] = (float) Math.atan2(positions[i3+1] - boxcenter.y, positions[i3] - boxcenter.x);
+//                uvmap[i2 + 1] = (float)(positions[i3+2] - boxcenter.z);
+                // box UV
+                double x = positions[i3] - minima.x; // - Math.floor(positions[i3]);
+                double y = positions[i3+1] - minima.y; // - Math.floor(positions[i3+1]);
+                double z = positions[i3+2] - minima.z; // - Math.floor(positions[i3+2]);
+
+                // [-1/2, 1/2]
+                x /= maxima.x - minima.x;
+                y /= maxima.y - minima.y;
+                z /= maxima.z - minima.z;
+                
+                x -= 0.5;
+                y -= 0.5;
+                z -= 0.5;
+                
           //      x *= 2;
           //      y *= 2;
           //      z *= 2;
@@ -3245,6 +3430,15 @@
 
                 z = Math.cos(angle/2);
                 
+                assert(z >= 0);
+                assert(z <= 1);
+                
+                /**/
+                //z = Math.pow(z, power); //1.08f);
+                
+                if (i == 0)
+                        System.out.println("power = " + power);
+                
                 // sqrt(k2*x2 + k2*z2 + y2) = length
                 // k2*x2 + k2*z2 = length2 - y2
                 // k2 = (length2 - y2) / (x2 + z2)
@@ -3255,7 +3449,7 @@
                     k /= x*x + y*y;
                 }
                 else
-                    GrafreeD.Assert(z == 1);
+                    Grafreed.Assert(z == 1);
                 
                 if (k < 0)
                     k = 0;
@@ -3264,6 +3458,7 @@
                 
                 x *= k;
                 y *= k;
+                /**/
                 
                 double max = Math.abs(x);
                 if (max < Math.abs(y))
@@ -3276,10 +3471,15 @@
                 }
 
             //    max = Math.sqrt(max*2)/2;
+//                double x2 = Math.pow(Math.abs(x), 1/power);
+//                double y2 = Math.pow(Math.abs(y), 1/power);
+//                double z2 = Math.pow(Math.abs(z), 1/power);
+//                max = Math.pow(x2 + y2 + z2, power);
                 
 //                if (!(max > 0))
-                    assert(max > 0);
-                
+                    //assert(max > 0);
+                    assert(max >= 0);
+                                    
                 x /= max;
                 y /= max;
                 z /= max;
@@ -3542,6 +3742,114 @@
      */
     }
 
+    void GenerateNormals2(boolean crease)
+    {
+        cVector tempVector = new cVector();
+        
+//        java.util.HashMap<cVector, cVector> tableBase = new java.util.HashMap<cVector, cVector>();
+//        
+//        
+//        for (int i=0; i<this.VertexCount(); i++)
+//        {
+//            Vertex v = this.GetVertex(i);
+//            
+//            tempVector.set(v);
+//            
+//            cVector n = tableBase.get(tempVector.ToFloat());
+//            
+//            if (n != null)
+//            {
+//                continue;
+//            }
+//            
+//            tableBase.put(new cVector(tempVector), new cVector(v.norm));
+//        }
+        
+        BoundaryRep tempSupport = this.support;
+        
+        this.support = null;
+        
+        BoundaryRep tempRep = (BoundaryRep)Grafreed.clone(this);
+        
+        this.support = tempSupport;
+        
+        //tempRep.Unstripify();
+        
+        tempRep.GenerateNormals(crease);
+        
+        boolean keepnormal = Vertex.normalmode;
+        boolean epsequal = Grafreed.epsequal;
+        
+        Vertex.normalmode = false;
+        Grafreed.epsequal = false; // A bit strange
+
+        // No need to have a match for vertex counts.
+        
+        java.util.HashMap<cVector, cVector> table = new java.util.HashMap<cVector, cVector>();
+        
+        for (int i=0; i<tempRep.VertexCount(); i++)
+        {
+            Vertex v = tempRep.GetVertex(i);
+            
+            cVector n = table.get(tempVector.ToFloat());
+            
+            if (v.norm.x == 1 && v.norm.y == 0 && v.norm.z == 0)
+            {
+                //continue;
+            }
+            
+            tempVector.set(v);
+            
+            //cVector nBase = tableBase.get(tempVector);
+            
+            //if (v.norm.dot(nBase) < 0.9)
+            //{
+            //    continue;
+            //}
+            
+            if (n != null && n.x == 1 && n.y == 0 && n.z == 0)
+            {
+                //continue;
+            }
+            
+            if (n != null)
+            {
+//                if (n.dot(v.norm) < 0)
+//                    n.sub(v.norm);
+//                else
+//                    n.add(v.norm);
+//                
+//                n.normalize();
+                continue;
+            }
+            
+            table.put(new cVector(tempVector), new cVector(v.norm));
+        }
+        
+        for (int i=0; i<this.VertexCount(); i++)
+        {
+            Vertex v = this.GetVertex(i);
+            
+            tempVector.set(v);
+            
+            cVector n = table.get(tempVector.ToFloat());
+            
+            //if (n.dot(v.norm) < 0)
+            if (n == null)
+                continue;
+            
+            if (v.norm == null)
+                v.norm = new cVector();
+            
+            LA.vecCopy(n, v.norm);
+            
+            this.SetVertex(v, i);
+        }
+        
+        Grafreed.epsequal = epsequal;
+        Vertex.normalmode = keepnormal;
+    }
+    
     void GenerateNormals(boolean crease)
     {
         boolean wastrim = trimmed;
@@ -3558,6 +3866,28 @@
         }
         
         Trim(true/*wastrim*/,true,crease,wasstrip,false);
+    }
+    
+    void GenerateNormalsMesh()
+    {
+        if (stripified)
+        {
+            Unstripify();
+        }
+        
+        if (trimmed)
+        {
+            normals = null;
+        }
+        else
+        {
+            for (int i=VertexCount(); --i>=0;)
+            {
+                Vertex v = GetVertex(i);
+
+                v.norm = null;
+            }
+        }
     }
     
     void GenNormalsJME()
@@ -3682,7 +4012,7 @@
             NormalGenerator ng;
             
             if (crease)
-                ng = new NormalGenerator(Math.PI/6); // default is 44 degrees (or Math.PI/3); // /4);
+                ng = new NormalGenerator(Math.PI/4); // default is 44 degrees (or Math.PI/3); // /4);
             else
                 ng = new NormalGenerator(Math.PI); // (Math.PI / 3); // /4);
             
@@ -3700,8 +4030,6 @@
                 //System.out.println("NEW = " + positions.length);
                 uvmap = new float[ta.getVertexCount() * 2];
                 
-                colors = new float[ta.getVertexCount()]; // * 3];
-
                 ta.getCoordinates(0, positions);
                 ta.getNormals(0, normals);
 //                ta.getColors(0, colors);
@@ -3709,12 +4037,24 @@
 
                 System.out.println("UV = " + uvmap[2] + ", " + uvmap[3] + ";");
 
+                colors = null;
+//                colors = new float[ta.getVertexCount()]; // * 3];
+//
+//                for (int i=colors.length; --i>=0;)
+//                {
+//                        colors[i] = 1;
+//                }
+                
                 triangles = new int[ta.getVertexCount()];
 
                 for (int i = 0; i < triangles.length; i++)
                 {
                     triangles[i] = i;
                 }
+                
+//                Untrim();
+                if (!trimmed)
+                    MergeNormals();
             }
         }
 
@@ -3742,12 +4082,18 @@
                 positions = new float[3 * ga.getVertexCount()];
                 normals = new float[3 * ga.getVertexCount()];
                 uvmap = new float[2 * ga.getVertexCount()];
-                colors = new float[1 * ga.getVertexCount()];
 
                 tsa.getCoordinates(0, positions);
                 tsa.getNormals(0, normals);
                 tsa.getTextureCoordinates(0, 0, uvmap);
            //     tsa.getColors(0, colors);
+
+                colors = null;
+//                colors = new float[1 * ga.getVertexCount()];
+//                for (int i=colors.length; --i>=0;)
+//                {
+//                        colors[i] = 1;
+//                }
 
                 int stripcount = tsa.getNumStrips();
                 triangles = new int[stripcount];
@@ -3756,6 +4102,7 @@
                 stripified = true;
             } catch (ClassCastException e)
             {
+                // ??? aug 2019
                 TriangleArray ta = (TriangleArray) ga;
 
                 positions = new float[3 * ga.getVertexCount()];
@@ -3770,6 +4117,10 @@
                 triangles = new int[1];
                 triangles[0] = 3;
             }
+            
+            //Untrim();
+            if (!trimmed)
+                MergeNormals();
         }
 
     /*
@@ -3819,6 +4170,42 @@
         }
 
         Vertex.normalmode = false;
+    }
+    
+    void MergeNormals()
+    {
+        assert(!trimmed);
+        
+        boolean smooth = Grafreed.smoothmode;
+        boolean link = Grafreed.linkUV;
+        Grafreed.smoothmode = true;
+        Grafreed.linkUV = true;
+
+        System.out.println("#Vertex = " + VertexCount());
+        System.out.println("#Face = " + FaceCount());
+
+        java.util.HashSet<Vertex> table = new java.util.HashSet<Vertex>();
+        
+        for (int i = 0; i < VertexCount(); i++)
+        {
+            Vertex v = GetVertex(i);
+
+            if (!table.contains(v))
+            {
+                table.add(v);
+            }
+        }
+
+        Grafreed.smoothmode = smooth;
+        Grafreed.linkUV = link;
+        
+//        for (int i = 0; i < VertexCount(); i++)
+//        {
+//            Vertex v = GetVertex(i);
+//
+//            table.add(v);
+//        }
+
     }
     
     static cVector temp1 = new cVector();
@@ -4428,7 +4815,7 @@
         }
     }
     
-    void CullVertex(javax.media.opengl.GL gl, boolean shadow)
+    void CullVertex(javax.media.opengl.GL glNOTUSED, boolean shadowNOTUSED)
     {
         CameraPane.glu.gluProject(vect5.x,vect5.y,vect5.z,
                 CameraPane.tempmat,0, CameraPane.tempmat2,0,
@@ -4460,14 +4847,14 @@
         // june 2014
 //        Camera parentcam = cam;
 //
-//        if (cam == CameraPane.theRenderer.cameras[0])
+//        if (cam == Globals.theRenderer.cameras[0])
 //        {
-//            parentcam = CameraPane.theRenderer.cameras[1];
+//            parentcam = Globals.theRenderer.cameras[1];
 //        }
 //
-//        if (cam == CameraPane.theRenderer.cameras[1])
+//        if (cam == Globals.theRenderer.cameras[1])
 //        {
-//            parentcam = CameraPane.theRenderer.cameras[0];
+//            parentcam = Globals.theRenderer.cameras[0];
 //        }
     
         gl.glGetDoublev(gl.GL_MODELVIEW_MATRIX, CameraPane.tempmat, 0);
@@ -4593,16 +4980,25 @@
             {
                 i3 = positions.length-3;
                 i2 = uvmap.length - 2;
-                new Exception().printStackTrace();
+                //new Exception().printStackTrace();
             }
             
             v./*pos.*/x = positions[i3];
             v./*pos.*/y = positions[i3 + 1];
             v./*pos.*/z = positions[i3 + 2];
 
-            v.norm.x = normals[i3];
-            v.norm.y = normals[i3 + 1];
-            v.norm.z = normals[i3 + 2];
+            if (normals == null)
+            {
+                v.norm.x = 0;
+                v.norm.y = 0;
+                v.norm.z = 0;
+            }
+            else
+            {
+                v.norm.x = normals[i3];
+                v.norm.y = normals[i3 + 1];
+                v.norm.z = normals[i3 + 2];
+            }
 
             v.s = uvmap[i2];
             v.t = uvmap[i2 + 1];
@@ -4893,7 +5289,7 @@
         return verticesCopy;
     }
 
-    void PreprocessOcclusion(CameraPane cp, double[][] transform)
+    void PreprocessOcclusion(iCameraPane cp, double[][] transform)
     {
         if (//!trimmed ||
                 AOdone)
@@ -4902,80 +5298,7 @@
             return;
         }
 
-        Camera keep = cp.renderCamera;
-        cp.renderCamera = localcamera;
-
-        if (trimmed)
-        {
-            float[] colors = new float[positions.length / 3];
-
-            int i3 = 0;
-            for (int i = 0; i < positions.length / 3; i++, i3 += 3)
-            {
-                if (normals[i3] == 0 && normals[i3+1] == 0 && normals[i3+2] == 0)
-                    continue;
-
-                from.set(positions[i3], positions[i3 + 1], positions[i3 + 2]);
-                to.set(positions[i3] + normals[i3],
-                        positions[i3 + 1] + normals[i3 + 1],
-                        positions[i3 + 2] + normals[i3 + 2]);
-                LA.xformPos(from, transform, from);
-                LA.xformPos(to, transform, to); // RIGID ONLY
-                localcamera.setAim(from, to);
-
-                CameraPane.occlusionbuffer.display();
-
-                if (CameraPane.DEBUG_OCCLUSION)
-                    cp.display(); // debug
-
-                colors[i] = cp.vertexOcclusion.r;
-                //colors[i3 + 1] = cp.vertexOcclusion.g;
-                //colors[i3 + 2] = cp.vertexOcclusion.b;
-
-                if ((i % 1000) == 0 && i != 0)
-                {
-            CameraPane.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
-                    //System.out.println("Color = " + cp.vertexOcclusion.r + ", " + cp.vertexOcclusion.g + ", " + cp.vertexOcclusion.b + "; " + (int)(100.0*i/(positions.length/3)) + "% done");
-                        System.out.println((int) (100.0 * i / (positions.length / 3)) + "% (" + i + " of " + (positions.length / 3) + ")");
-                }
-            }
-
-            this.colors = colors;
-        }
-        else
-        {
-            for (int i = 0; i < VertexCount(); i++)
-            {
-                Vertex v = GetVertex(i);
-                
-                if (v.norm.x == 0 && v.norm.y == 0 && v.norm.z == 0)
-                    continue;
-
-                from.set(v.x, v.y, v.z);
-                to.set(v.x+v.norm.x, v.y+v.norm.y, v.z+v.norm.z);
-                LA.xformPos(from, transform, from);
-                LA.xformPos(to, transform, to); // RIGID ONLY
-                localcamera.setAim(from, to);
-
-                CameraPane.occlusionbuffer.display();
-
-                if (CameraPane.DEBUG_OCCLUSION)
-                    cp.display(); // debug
-
-                v.AO = cp.vertexOcclusion.r;
-
-                if ((i % 1000) == 0 && i != 0)
-                {
-            CameraPane.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
-                    //System.out.println("Color = " + cp.vertexOcclusion.r + ", " + cp.vertexOcclusion.g + ", " + cp.vertexOcclusion.b + "; " + (int)(100.0*i/(positions.length/3)) + "% done");
-                        System.out.println((int) (100.0 * i / VertexCount()) + "% (" + i + " of " + VertexCount() + ")");
-                }
-            }
-        }
-
-        //System.out.println("done.");
-
-        cp.renderCamera = keep;
+                cp.PrepOcclusion(this, transform);
         
         AOdone = true;
     }
@@ -5390,17 +5713,27 @@
     
     transient int nbbadfaces; // ?? = 1000000;
     
-    int ChooseTriangle()
+    /*
+     */
+    int ChooseTriangle(boolean firstEquilateral)
     {
         int chosen = -1;
         
         double minweight = 1E10;
         
+        int step = 8; // ?
+        
+        if (firstEquilateral)
+            step = 1;
+        
         nbbadfaces = 0;
-        for (int i=0; i<faces.size(); i+=8)
+        for (int i=0; i<faces.size(); i+=step)
 //        for (int i=faces.size(); (i-=8)>=0;)
         {
             Face face = (Face) faces.get(i);
+            
+            if (face.used)
+                continue;
             
             if (!Valid(face))
             {
@@ -5410,6 +5743,15 @@
             
             if (Boundary(face))
                 continue;
+            
+//            if (Boundary(face.p))
+//                continue;
+//            
+//            if (Boundary(face.q))
+//                continue;
+//            
+//            if (Boundary(face.r))
+//                continue;
             
             if (!ValidValence(face))
                 continue;
@@ -5422,22 +5764,55 @@
         //??    if (face.weight < 0)
         //        continue;
             
-            double K = 1; // 0.01; // .25;
-            
-            double factor = (1-K)*face.nbiterations + K; //*face.weight;
-            
-            double weight = FaceWeight(face); // *Math.pow(PerimeterMax(face),0.25)*factor;
-            
-            if (minweight > weight)
+            if (firstEquilateral)
             {
-                minweight = weight;
+                if (OneFaceUsed(links.get(face.p)))
+                    continue;
+
+                if (OneFaceUsed(links.get(face.q)))
+                    continue;
+
+                if (OneFaceUsed(links.get(face.r)))
+                    continue;
+
                 chosen = i;
-                if (minweight == 0)
-                    break;
+                break;
+            }
+            else
+            {
+                double K = 1; // 0.01; // .25;
+
+                double factor = (1-K)*face.nbiterations + K; //*face.weight;
+
+                double weight = FaceWeight(face); // *Math.pow(PerimeterMax(face),0.25)*factor;
+
+                if (minweight > weight)
+                {
+                    minweight = weight;
+                    chosen = i;
+                    if (minweight == 0)
+                        break;
+                }
             }
         }
         
         return chosen;
+    }
+
+    private boolean OneFaceUsed(Vector<Face> faces)
+    {
+        if (faces.size() != 6)
+            return true;
+                
+        for (int i=0; i<6; i+=1)
+        {
+            if (faces.get(i).used)
+            {
+                return true;
+            }
+        }
+
+        return false;
     }
         
     static boolean remove3valence = true;
@@ -5473,7 +5848,7 @@
                 }
                 else
                 {
-                    assert(links.size() == vertices.size());
+                // TODO   Grafreed.Assert(links.size() == vertices.size());
                     
                     links.setSize(vertices.size());
                     for (int i=vertices.size(); --i>=0;)
@@ -5481,6 +5856,7 @@
 //                        linkstouched[i] = false;
                         if (links.get(i) == null) // ??
                         {
+                            new Exception().printStackTrace();
                             links.set(i, new Vector(8));
 //                            linkstouched[i] = true;
                         }
@@ -5491,6 +5867,8 @@
                     }
                 }
 
+                boolean once = false;
+                
                 for (int i=faces.size(); --i>=0;)
                 {
                     Face face = (Face) faces.get(i);
@@ -5502,6 +5880,9 @@
                     //if (linkstouched[face.r])
                         links.get(face.r).add(face);
                     
+                        if (face.used)
+                            once = true;
+                        
                     face.good = 1;
                     face.boundary = -1;
                 }
@@ -6273,6 +6654,7 @@
     
     void InitWeights()
     {
+                new Exception().printStackTrace();
         System.exit(0);
         int n = 0;
         int b = 0;
@@ -6866,6 +7248,10 @@
             return (face.boundary = 1) == 1;
         }
         
+        // June 2019
+        if (true)
+            return (face.boundary = 0) == 1;
+        
         // reverse triangle test
         q1.set(p);
         q2.set(q);
@@ -7230,7 +7616,8 @@
             {
                 if (f3.p == f0.p)
                 {
-                    assert(false);
+//                    assert(false);
+                    new Exception().printStackTrace();
                     f0.r = f3.q;
                 }
                 else
@@ -7314,7 +7701,7 @@
             //InitWeights();
         }
         
-        int chosen = ChooseTriangle(); // Best is slow and not really better
+        int chosen = ChooseTriangle(true); // Best is slow and not really better
         
         if (chosen == -1)
         {
@@ -7328,7 +7715,7 @@
                 //remove3valence = false;
              //   InitWeights();
 
-                chosen = ChooseTriangle();
+                chosen = ChooseTriangle(true);
             }
         }
         
@@ -7604,7 +7991,7 @@
     
 //    boolean lock;
     
-    void SplitInTwo(boolean reduction34, boolean onlyone)
+    boolean SplitInTwo(boolean reduction34, boolean onlyone)
     {
         if (stripified)
         {
@@ -7632,7 +8019,7 @@
             s3 = new cVector();
         }
         
-        CameraPane.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
+        Globals.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
         
         try
         {
@@ -7641,12 +8028,12 @@
         {
             System.err.println("EXCEPTION CAUGHT");
             e.printStackTrace();
-            return;
+            return false;
         } catch (Error e)
         {
             System.err.println("ERROR CAUGHT");
             e.printStackTrace();
-            return;
+            return false;
         }
         
         System.out.println("# faces = " + faces.size());
@@ -7656,6 +8043,7 @@
         {
             Face face = (Face) faces.get(i);
             
+            face.used = false;
             face.nbiterations = 1;
             face.weight = -1;
             face.boundary = -1;
@@ -7707,6 +8095,11 @@
         nbbadfaces = faces.size();
         //remove3valence = true;
        
+        int count = 2;
+        
+        if (onlyone)
+            count = 1;
+        
         firstpass = true;
         
         int n = faces.size();
@@ -7722,12 +8115,13 @@
             System.out.print('.');
         }
         System.out.println();
+        boolean atleastone = false;
         int i = 0;
-        while (reduction34 || faces.size() > n/2)
+        while (true) // reduction34 || faces.size() > n/2)
         {
             if (i++%100 == 0)
             {
-                CameraPane.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
+                Globals.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.WAIT_CURSOR));
                 System.out.println("#faces = " + faces.size());
             //    if (i != 1)
             //        break;
@@ -7745,6 +8139,8 @@
                 {
                     if (!RemoveOneTriangle())
                         break;
+                    
+                    atleastone = true;
                 }
          //       if (iterationcount == 0)
          //           break;
@@ -7755,8 +8151,8 @@
                 break;
             }
             firstpass = false;
-            if (onlyone)
-                break; // one triangle only
+//            if (--count<0 && !reduction34)
+//                break; // one triangle only
         }
         
         InitLinks(false); // for further display
@@ -7771,7 +8167,9 @@
         //Trim(true,cJME.gennormals,true,false); // doesn't work
         Trim(true,false,false,false,false);
         
-        CameraPane.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
+        Globals.theRenderer.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
+        
+        return atleastone;
     }
     
     void UpdateIndices(Face face, Face minface)
@@ -7784,18 +8182,21 @@
             face.p = minface.p;
             //if (leafweights)
                 face.good = 0; // false;
+                face.used = true;
         }
         if (face.q == minface.p || face.q == minface.q || face.q == minface.r)
         {
             face.q = minface.p;
             //if (leafweights)
                 face.good = 0; // false;
+                face.used = true;
         }
         if (face.r == minface.p || face.r == minface.q || face.r == minface.r)
         {
             face.r = minface.p;
             //if (leafweights)
                 face.good = 0; // false;
+                face.used = true;
         }
 
         if (face.p >/*=*/ minface.q && face.p < minface.r)
@@ -7855,50 +8256,50 @@
             if (v == 2)
                 vert = minface.r;
 //            Face face = (Face) faces.get(i);
-        Vector<Face> vertfaces = links.get(vert);
-        for (int i=vertfaces.size(); --i>=0;)
-        {
-            Face face = (Face) vertfaces.get(i);
-            
-         //   if (face.weight == 10000)
-         //       continue;
-            
-            if (face.p == minface.p || face.q == minface.p || face.r == minface.p ||
-                face.p == minface.q || face.q == minface.q || face.r == minface.q ||
-                face.p == minface.r || face.q == minface.r || face.r == minface.r)
+            Vector<Face> vertfaces = links.get(vert);
+            for (int i=vertfaces.size(); --i>=0;)
             {
-                if (!leafweights)
+                Face face = (Face) vertfaces.get(i);
+
+             //   if (face.weight == 10000)
+             //       continue;
+
+                if (face.p == minface.p || face.q == minface.p || face.r == minface.p ||
+                    face.p == minface.q || face.q == minface.q || face.r == minface.q ||
+                    face.p == minface.r || face.q == minface.r || face.r == minface.r)
                 {
-//                    if(minfaceweight <= 0)
-//                    assert(minfaceweight > 0);
-//                    
-//                    //FaceWeight(face);
-//                    if(face.weight < 0)
-//                    assert(face.weight >= 0);
-                    
-                    face.weight += minfaceweight;
-                    
-//                    if (face.weight >= 10000)
-//                        assert(face.weight < 10000);
+                    if (!leafweights)
+                    {
+    //                    if(minfaceweight <= 0)
+    //                    assert(minfaceweight > 0);
+    //                    
+    //                    //FaceWeight(face);
+    //                    if(face.weight < 0)
+    //                    assert(face.weight >= 0);
+
+                        face.weight += minfaceweight;
+
+    //                    if (face.weight >= 10000)
+    //                        assert(face.weight < 10000);
+                    }
+                    else
+                        face.weight = -1;
+
+                    face.nbiterations += 1;
+                    face.boundary = -1;
+
+                    Vertex p = (Vertex)vertices.get(face.p);
+                    Vertex q = (Vertex)vertices.get(face.q);
+                    Vertex r = (Vertex)vertices.get(face.r);
+
+                    p.boundary = -1;
+                    q.boundary = -1;
+                    r.boundary = -1;
                 }
                 else
-                    face.weight = -1;
-                
-                face.nbiterations += 1;
-                face.boundary = -1;
-                
-                Vertex p = (Vertex)vertices.get(face.p);
-                Vertex q = (Vertex)vertices.get(face.q);
-                Vertex r = (Vertex)vertices.get(face.r);
-
-                p.boundary = -1;
-                q.boundary = -1;
-                r.boundary = -1;
+                    assert(false);
             }
-            else
-                assert(false);
         }
-    }
         
 //        TouchVertex(minface.p);
 //        TouchVertex(minface.q);
@@ -8099,6 +8500,7 @@
         for (int i=vertfaces.size(); --i>=0;)
         {
             Face face = (Face) vertfaces.get(i);
+            face.used = true;
             face.good = 0; // false;
             if (leafweights)
                 face.weight = -1;
@@ -8145,7 +8547,7 @@
         if (!trimmed)
             return;
         
-        GrafreeD.linkUV = false;
+        Grafreed.linkUV = false;
         
         try
         {
@@ -8353,9 +8755,6 @@
         return "trim = " + trimmed + "; stripped = " + stripified + "; colors = " + colors + "; faces = " + (faces!=null?faces.size():null) + "; triangles = " + (triangles!=null?triangles.length:null) + "; indices = " + indices;
     }
     
-    static Camera localcamera = new Camera();
-    static cVector from = new cVector();
-    static cVector to = new cVector();
     boolean trimmed = false;
     boolean stripified = false;
     transient boolean AOdone = false;
@@ -8363,8 +8762,10 @@
     /*transient*/ int maxIndexV = 0;
     /*transient*/ int bufV, bufF;
     // Raw version
-    private float[] positions;
-    private float[] normals;
+    //private
+            float[] positions;
+    //private
+            float[] normals;
     float[] colors;
     private float[] uvmap;
     private int[] triangles;
@@ -8378,7 +8779,8 @@
     int[] startvertices;
     float[] averagepoints;
     float[] extremepoints;
-    float[] supportsizes; // distance of closest point
+    float[] supportminsize; // distance of closest point
+    float[] supportmaxsize; // distance of fartest point
     
     transient Hashtable vertextable;
     /*transient*/ private Vertex[] verticesCopy;

--
Gitblit v1.6.2