public void Update()
    {
        if (sj.is_done && sj.is_processing)
        {
            var smr = renal.GetComponent <SkinnedMeshRenderer>();

            smr.sharedMesh.MarkDynamic();
            smr.sharedMesh.subMeshCount = sj.indices.Length;
            for (int j = 0; j < sj.indices.Length; j++)
            {
                int[] array;
                if (sj.indices[j].Length > 0)
                {
                    array = sj.indices[j];
                }
                else
                {
                    array = new int[] { 0, 0, 0 };
                }
                smr.sharedMesh.SetIndices(array, MeshTopology.Triangles, j);
            }
            //smr.sharedMesh.triangles = sj.triangles;
            var shapes           = renal.GetComponent <FlexShapeMatching>();
            var plane            = new Plane(sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2]);
            var new_bone_weights = smr.sharedMesh.boneWeights;
            foreach (var vidx in sj.affected_vertices)
            {
                var v     = sj.transform.MultiplyPoint3x4(sj.vertices[vidx]);
                var bw    = smr.sharedMesh.boneWeights[vidx];
                var bIdxs = new List <weight_thing> {
                    new weight_thing(bw.boneIndex0, bw.weight0),
                    new weight_thing(bw.boneIndex1, bw.weight1),
                    new weight_thing(bw.boneIndex2, bw.weight2),
                    new weight_thing(bw.boneIndex3, bw.weight3)
                };
                bIdxs = bIdxs.Select(bidx => plane.SameSide(v, CutFlexUtil.shape_to_world(bidx.bone_idx, shapes)) ?
                                     bidx : new weight_thing(bidx.bone_idx, 0.0f)).ToList();
                bIdxs.Sort((lhs, rhs) => lhs.weight > rhs.weight ? -1 : 1);

                var weight_sum = bIdxs.Sum(bidx => bidx.weight);
                bw.boneIndex0 = bIdxs[0].bone_idx;
                bw.weight0    = bIdxs[0].weight / weight_sum;
                bw.boneIndex1 = bIdxs[1].bone_idx;
                bw.weight1    = bIdxs[1].weight / weight_sum;
                bw.boneIndex2 = bIdxs[2].bone_idx;
                bw.weight2    = bIdxs[2].weight / weight_sum;
                bw.boneIndex3 = bIdxs[3].bone_idx;
                bw.weight3    = bIdxs[3].weight / weight_sum;

                new_bone_weights[vidx] = bw;
            }
            smr.sharedMesh.boneWeights = new_bone_weights;
            sj.is_processing           = false;
        }
    }
 public static void find_triangles(slice_job sj)
 {
     sj.affected_vertices = new List <int>();
     for (int m = 0; m < sj.indices.Count(); ++m)
     {
         var new_indices = new List <int>();
         for (int i = 0; i < sj.indices[m].Count(); i += 3)
         {
             var p1 = sj.transform.MultiplyPoint3x4(sj.vertices[sj.indices[m][i + 0]]);
             var p2 = sj.transform.MultiplyPoint3x4(sj.vertices[sj.indices[m][i + 1]]);
             var p3 = sj.transform.MultiplyPoint3x4(sj.vertices[sj.indices[m][i + 2]]);
             if (CutFlexUtil.intersects_quad(p1, p2, sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2], sj.cutting_quad[3]) ||
                 CutFlexUtil.intersects_quad(p2, p3, sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2], sj.cutting_quad[3]) ||
                 CutFlexUtil.intersects_quad(p3, p1, sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2], sj.cutting_quad[3]))
             {
                 sj.affected_vertices.Add(sj.indices[m][i + 0]);
                 sj.affected_vertices.Add(sj.indices[m][i + 1]);
                 sj.affected_vertices.Add(sj.indices[m][i + 2]);
             }
             else
             {
                 new_indices.Add(sj.indices[m][i + 0]);
                 new_indices.Add(sj.indices[m][i + 1]);
                 new_indices.Add(sj.indices[m][i + 2]);
             }
         }
         sj.indices[m] = new_indices.ToArray();
     }
     //var new_triangles = new List<int>();
     //for (int i = 0; i < sj.triangles.Length; i += 3)
     //{
     //    var p1 = sj.transform.MultiplyPoint3x4(sj.vertices[sj.triangles[i + 0]]);
     //    var p2 = sj.transform.MultiplyPoint3x4(sj.vertices[sj.triangles[i + 1]]);
     //    var p3 = sj.transform.MultiplyPoint3x4(sj.vertices[sj.triangles[i + 2]]);
     //    if (!CutFlexUtil.intersects_quad(p1, p2, sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2], sj.cutting_quad[3]) &&
     //        !CutFlexUtil.intersects_quad(p2, p3, sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2], sj.cutting_quad[3]) &&
     //        !CutFlexUtil.intersects_quad(p3, p1, sj.cutting_quad[0], sj.cutting_quad[1], sj.cutting_quad[2], sj.cutting_quad[3]))
     //    {
     //        new_triangles.Add(sj.triangles[i + 0]);
     //        new_triangles.Add(sj.triangles[i + 1]);
     //        new_triangles.Add(sj.triangles[i + 2]);
     //    }
     //}
     //sj.triangles = new_triangles.ToArray();
     sj.is_done = true;
 }
 private void queue_work(Transform[] pts)
 {
     if (!sj.is_processing && CutFlexUtil.CutFlexSoft(renal.transform, pts[0].position, pts[1].position, pts[2].position, pts[3].position))
     {
         var mesh = new Mesh();
         renal.GetComponent <SkinnedMeshRenderer>().BakeMesh(mesh);
         sj.indices = new int[mesh.subMeshCount][];
         for (int i = 0; i < mesh.subMeshCount; i++)
         {
             sj.indices[i] = mesh.GetIndices(i);
         }
         //sj.triangles = mesh.triangles;
         sj.vertices     = mesh.vertices;
         sj.transform    = renal.transform.localToWorldMatrix;
         sj.cutting_quad = new Vector3[4] {
             pts[0].position, pts[1].position, pts[2].position, pts[3].position
         };
         sj.is_processing = true;
         sj.is_done       = false;
         //System.Threading.ThreadPool.QueueUserWorkItem((state_info) => slice_mesh.find_triangles(sj));
         slice_mesh.find_triangles(sj);
     }
 }