From b3ae4e889872ca0b9ca76f1d17b2f0b961226729 Mon Sep 17 00:00:00 2001
From: Normand Briere <nbriere@noware.ca>
Date: Mon, 05 Aug 2019 21:48:55 -0400
Subject: [PATCH] Fix physics UI

---
 BoundaryRep.java |  681 +++++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 570 insertions(+), 111 deletions(-)

diff --git a/BoundaryRep.java b/BoundaryRep.java
index 729177a..79ff6fe 100644
--- a/BoundaryRep.java
+++ b/BoundaryRep.java
@@ -161,6 +161,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 +173,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 +240,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 +261,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 +323,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 +383,7 @@
             supports = supports2;
         }
         
-        return supports;
+        return cachesupports = supports;
     }
     
     double Distance2(Vertex v, Vertex v2, double dist2beat, double[][] toRoot, int k)
@@ -500,7 +530,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.05f; // 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 +628,7 @@
 //                ;
         //
 
-        supportsize = supportsizes[subsupport];
+        supportsize = supportminsize[subsupport];
         
         double K = supportsize / distmax;
         
@@ -650,7 +680,8 @@
     //    if (supportsize * fadefactor > 1)
     //        return 1;
         
-        return supportsize * fadefactor;
+        return //supportsize *
+                supportsize * fadefactor;
     }
     
     void RecomputeBasis(BoundaryRep other, double[][] toRoot, Vertex v)
@@ -952,7 +983,7 @@
         
         // sept 2017 SEUIL = 0.1; // aout 2013
         
-        supports = InitConnections(other);
+        supports = other.InitConnections();
         
         other.supports = supports; // should be the other way around...
         
@@ -1518,7 +1549,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 +1579,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 +1926,7 @@
             return;
         }
         
-    //    System.exit(0);
+        // System.exit(0);
         
         cVector vect = new cVector();
         cVector normal = new cVector();
@@ -1966,7 +1997,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 +2281,8 @@
     
     transient int lastsoundtime;
     
+    transient boolean once = false;
+    
     void setMasterThis0(BoundaryRep other, double[][] toRoot, boolean smooth, boolean marked)
     {
         if (LA.isIdentity(toRoot))
@@ -2302,7 +2338,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,7 +2701,7 @@
         if (false) // slow && stepout && onein)
         {
             // sound
-            cVector eye = CameraPane.theRenderer.eyeCamera.location;
+            cVector eye = Globals.theRenderer.EyeCamera().location;
 
             Vertex v = GetVertex(0);
 
@@ -2670,7 +2710,7 @@
 
             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 = Globals.framecount;
             }
@@ -3098,6 +3138,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 +3196,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 +3280,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 +3425,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 +3444,7 @@
                     k /= x*x + y*y;
                 }
                 else
-                    GrafreeD.Assert(z == 1);
+                    Grafreed.Assert(z == 1);
                 
                 if (k < 0)
                     k = 0;
@@ -3264,6 +3453,7 @@
                 
                 x *= k;
                 y *= k;
+                /**/
                 
                 double max = Math.abs(x);
                 if (max < Math.abs(y))
@@ -3276,10 +3466,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 +3737,111 @@
      */
     }
 
+    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.GenerateNormals2(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;
+            
+            LA.vecCopy(n, v.norm);
+            
+            this.SetVertex(v, i);
+        }
+        
+        Grafreed.epsequal = epsequal;
+        Vertex.normalmode = keepnormal;
+    }
+    
     void GenerateNormals(boolean crease)
     {
         boolean wastrim = trimmed;
@@ -3558,6 +3858,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 +4004,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);
             
@@ -3715,6 +4037,10 @@
                 {
                     triangles[i] = i;
                 }
+                
+//                Untrim();
+                if (!trimmed)
+                    MergeNormals();
             }
         }
 
@@ -3748,6 +4074,11 @@
                 tsa.getNormals(0, normals);
                 tsa.getTextureCoordinates(0, 0, uvmap);
            //     tsa.getColors(0, colors);
+                
+                for (int i=colors.length; --i>=0;)
+                {
+                        colors[i] = 1;
+                }
 
                 int stripcount = tsa.getNumStrips();
                 triangles = new int[stripcount];
@@ -3770,6 +4101,10 @@
                 triangles = new int[1];
                 triangles[0] = 3;
             }
+            
+            //Untrim();
+            if (!trimmed)
+                MergeNormals();
         }
 
     /*
@@ -3819,6 +4154,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 +4799,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 +4831,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 +4964,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];
@@ -5317,17 +5697,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))
             {
@@ -5337,6 +5727,15 @@
             
             if (Boundary(face))
                 continue;
+            
+//            if (Boundary(face.p))
+//                continue;
+//            
+//            if (Boundary(face.q))
+//                continue;
+//            
+//            if (Boundary(face.r))
+//                continue;
             
             if (!ValidValence(face))
                 continue;
@@ -5349,22 +5748,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;
@@ -5400,7 +5832,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;)
@@ -5408,6 +5840,7 @@
 //                        linkstouched[i] = false;
                         if (links.get(i) == null) // ??
                         {
+                            new Exception().printStackTrace();
                             links.set(i, new Vector(8));
 //                            linkstouched[i] = true;
                         }
@@ -5418,6 +5851,8 @@
                     }
                 }
 
+                boolean once = false;
+                
                 for (int i=faces.size(); --i>=0;)
                 {
                     Face face = (Face) faces.get(i);
@@ -5429,6 +5864,9 @@
                     //if (linkstouched[face.r])
                         links.get(face.r).add(face);
                     
+                        if (face.used)
+                            once = true;
+                        
                     face.good = 1;
                     face.boundary = -1;
                 }
@@ -6200,6 +6638,7 @@
     
     void InitWeights()
     {
+                new Exception().printStackTrace();
         System.exit(0);
         int n = 0;
         int b = 0;
@@ -6793,6 +7232,10 @@
             return (face.boundary = 1) == 1;
         }
         
+        // June 2019
+        if (true)
+            return (face.boundary = 0) == 1;
+        
         // reverse triangle test
         q1.set(p);
         q2.set(q);
@@ -7242,7 +7685,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)
         {
@@ -7256,7 +7699,7 @@
                 //remove3valence = false;
              //   InitWeights();
 
-                chosen = ChooseTriangle();
+                chosen = ChooseTriangle(true);
             }
         }
         
@@ -7532,7 +7975,7 @@
     
 //    boolean lock;
     
-    void SplitInTwo(boolean reduction34, boolean onlyone)
+    boolean SplitInTwo(boolean reduction34, boolean onlyone)
     {
         if (stripified)
         {
@@ -7560,7 +8003,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
         {
@@ -7569,12 +8012,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());
@@ -7584,6 +8027,7 @@
         {
             Face face = (Face) faces.get(i);
             
+            face.used = false;
             face.nbiterations = 1;
             face.weight = -1;
             face.boundary = -1;
@@ -7635,6 +8079,11 @@
         nbbadfaces = faces.size();
         //remove3valence = true;
        
+        int count = 2;
+        
+        if (onlyone)
+            count = 1;
+        
         firstpass = true;
         
         int n = faces.size();
@@ -7650,12 +8099,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;
@@ -7673,6 +8123,8 @@
                 {
                     if (!RemoveOneTriangle())
                         break;
+                    
+                    atleastone = true;
                 }
          //       if (iterationcount == 0)
          //           break;
@@ -7683,8 +8135,8 @@
                 break;
             }
             firstpass = false;
-            if (onlyone)
-                break; // one triangle only
+//            if (--count<0 && !reduction34)
+//                break; // one triangle only
         }
         
         InitLinks(false); // for further display
@@ -7699,7 +8151,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)
@@ -7712,18 +8166,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)
@@ -7783,50 +8240,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);
@@ -8027,6 +8484,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;
@@ -8073,7 +8531,7 @@
         if (!trimmed)
             return;
         
-        GrafreeD.linkUV = false;
+        Grafreed.linkUV = false;
         
         try
         {
@@ -8305,7 +8763,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