예제 #1
0
        public Mesh Catmull_Clark(Mesh x)
        {
            Mesh           mesh = new Mesh();
            List <Point3d> pv   = new List <Point3d>();
            List <Point3d> pe   = new List <Point3d>();
            List <Point3d> pf   = new List <Point3d>();

            Rhino.Geometry.Collections.MeshTopologyVertexList vs = x.TopologyVertices;
            Rhino.Geometry.Collections.MeshTopologyEdgeList   el = x.TopologyEdges;
            for (int i = 0; i < x.Faces.Count; i++)
            {
                int[]   index = vs.IndicesFromFace(i);
                Point3d pf1   = new Point3d();
                for (int j = 0; j < index.Length; j++)
                {
                    pf1 += vs[index[j]];
                }
                pf1 /= index.Length;
                pf.Add(pf1);
            }
            for (int i = 0; i < el.Count; i++)
            {
                IndexPair pair  = el.GetTopologyVertices(i);
                Point3d   pe1   = vs[pair.I] + vs[pair.J];
                int[]     index = el.GetConnectedFaces(i);
                if (index.Length == 2)
                {
                    pe1 += pf[index[0]] + pf[index[1]];
                    pe1 /= 4.0;
                }
                else
                {
                    pe1 = pe1 / 2.0;
                }
                pe.Add(pe1);
            }
            for (int i = 0; i < vs.Count; i++)
            {
                int[]   index  = vs.ConnectedEdges(i);
                int[]   index2 = vs.ConnectedFaces(i);
                Point3d V      = vs[i];
                if (index.Length == index2.Length)
                {
                    Point3d R = new Point3d(), Q = new Point3d();
                    for (int j = 0; j < index.Length; j++)
                    {
                        IndexPair pair = el.GetTopologyVertices(index[j]);
                        Point3d   pe1  = (vs[pair.I] + vs[pair.J]) * 0.5f;
                        R += pe1;
                    }
                    R /= index.Length;
                    for (int j = 0; j < index2.Length; j++)
                    {
                        Q += pf[index2[j]];
                    }
                    Q /= index2.Length;

                    int n = vs.ConnectedTopologyVertices(i).Length;
                    V  = Q + (R * 2) + V * (n - 3);
                    V /= n;
                }
                else
                {
                    Point3d R = new Point3d();
                    for (int j = 0; j < index.Length; j++)
                    {
                        if (el.GetConnectedFaces(index[j]).Length == 1)
                        {
                            IndexPair pair = el.GetTopologyVertices(index[j]);
                            R += vs[pair.I] + vs[pair.J];
                        }
                    }
                    V = R * 0.125f + V * 0.5;
                }
                pv.Add(V);
            }
            mesh.Vertices.AddVertices(pv);
            mesh.Vertices.AddVertices(pe);
            mesh.Vertices.AddVertices(pf);
            for (int i = 0; i < x.Faces.Count; i++)
            {
                int[] index = vs.IndicesFromFace(i);
                if (x.Faces[i].IsQuad)
                {
                    int pc = pv.Count + pe.Count + i;
                    int p1 = index[0]; int p2 = index[1]; int p3 = index[2]; int p4 = index[3];
                    int p12 = el.GetEdgeIndex(p1, p2) + pv.Count;
                    int p23 = el.GetEdgeIndex(p2, p3) + pv.Count;
                    int p34 = el.GetEdgeIndex(p3, p4) + pv.Count;
                    int p41 = el.GetEdgeIndex(p4, p1) + pv.Count;
                    mesh.Faces.AddFace(p1, p12, pc, p41);
                    mesh.Faces.AddFace(p12, p2, p23, pc);
                    mesh.Faces.AddFace(pc, p23, p3, p34);
                    mesh.Faces.AddFace(p41, pc, p34, p4);
                }
                else if (x.Faces[i].IsTriangle)
                {
                    int pc = pv.Count + pe.Count + i;
                    int p1 = index[0]; int p2 = index[1]; int p3 = index[2];
                    int p12 = el.GetEdgeIndex(p1, p2) + pv.Count;
                    int p23 = el.GetEdgeIndex(p2, p3) + pv.Count;
                    int p31 = el.GetEdgeIndex(p3, p1) + pv.Count;
                    mesh.Faces.AddFace(p1, p12, pc, p31);
                    mesh.Faces.AddFace(p12, p2, p23, pc);
                    mesh.Faces.AddFace(pc, p23, p3, p31);
                }
            }
            mesh.UnifyNormals();
            return(mesh);
        }
예제 #2
0
        public void CaculateAm()
        {
            for (int i = 0; i < mesh.Faces.Count; i++)
            {
                int[]   f      = vs.IndicesFromFace(i);
                Point3d p1     = vs[f[0]];
                Point3d p2     = vs[f[1]];
                Point3d p3     = vs[f[2]];
                Circle  circle = new Circle(p1, p2, p3);
                double  a      = p1.DistanceTo(p2);
                double  b      = p1.DistanceTo(p3);
                double  c      = p2.DistanceTo(p3);
                // Print(f.Length.ToString());
                // Print(a.ToString() + "/" + b.ToString() + "/" + c.ToString());
                Point3d ci   = new Point3d();
                int     sign = 0;
                if (c >= a && c >= b)
                {
                    if ((c * c) < (a * a + b * b))
                    {
                        ci = circle.Center;
                    }
                    else
                    {
                        ci = (p2 + p3) / 2; sign = 1;
                    }
                }
                else if (a >= c && a >= b)
                {
                    if ((a * a) < (c * c + b * b))
                    {
                        ci = circle.Center;
                    }
                    else
                    {
                        ci = (p2 + p1) / 2; sign = 2;
                    }
                }
                else if (b >= a && b >= c)
                {
                    if ((b * b) < (a * a + c * c))
                    {
                        ci = circle.Center;
                    }
                    else
                    {
                        ci = (p1 + p3) / 2; sign = 3;
                    }
                }
                else
                { //Print("error");
                }

                Point3d p1p2 = (p1 + p2) / 2;
                Point3d p1p3 = (p1 + p3) / 2;
                Point3d p2p3 = (p3 + p2) / 2;

                if (sign == 0)
                {
                    ps[f[0]].Am += areaTri(ci, p1, p1p2) + areaTri(ci, p1, p1p3);
                    ps[f[1]].Am += areaTri(ci, p2, p1p2) + areaTri(ci, p2, p2p3);
                    ps[f[2]].Am += areaTri(ci, p3, p1p3) + areaTri(ci, p3, p2p3);
                }
                else if (sign == 1)
                {
                    ps[f[1]].Am += areaTri(ci, p2, p1p2);
                    ps[f[2]].Am += areaTri(ci, p3, p1p3);
                    ps[f[0]].Am += areaTri(ci, p1, p1p2) + areaTri(ci, p1, p1p3);
                }
                else if (sign == 2)
                {
                    ps[f[1]].Am += areaTri(ci, p2, p2p3);
                    ps[f[0]].Am += areaTri(ci, p1, p1p3);
                    ps[f[2]].Am += areaTri(ci, p3, p1p3) + areaTri(ci, p3, p2p3);
                }
                else if (sign == 3)
                {
                    ps[f[0]].Am += areaTri(ci, p1, p1p2);
                    ps[f[2]].Am += areaTri(ci, p3, p2p3);
                    ps[f[1]].Am += areaTri(ci, p2, p1p2) + areaTri(ci, p2, p2p3);
                }
                else
                {// Print("error");
                }
                //////////////////
                ps[f[0]].KG += Vector3d.VectorAngle(p2 - p1, p3 - p1);
                ps[f[1]].KG += Vector3d.VectorAngle(p1 - p2, p3 - p2);
                ps[f[2]].KG += Vector3d.VectorAngle(p2 - p3, p1 - p3);
                /////////////////
            }
            for (int i = 0; i < el.Count; i++)
            {
                int[] f = el.GetConnectedFaces(i);
                if (f.Length == 2)
                {
                    ///////////////
                    int pi1 = el.GetTopologyVertices(i).I;
                    int pi2 = el.GetTopologyVertices(i).J;
                    int pf1 = 0; int pf2 = 0;

                    int[] vi1 = vs.IndicesFromFace(f[0]);
                    for (int j = 0; j < 3; j++)
                    {
                        if (vi1[j] != pi1 && vi1[j] != pi2)
                        {
                            pf1 = vi1[j]; break;
                        }
                    }
                    int[] vi2 = vs.IndicesFromFace(f[1]);
                    for (int j = 0; j < 3; j++)
                    {
                        if (vi2[j] != pi1 && vi2[j] != pi2)
                        {
                            pf2 = vi2[j]; break;
                        }
                    }
                    double ang1 = Vector3d.VectorAngle(vs[pi1] - vs[pf1], vs[pi2] - vs[pf1]);
                    double ang2 = Vector3d.VectorAngle(vs[pi1] - vs[pf2], vs[pi2] - vs[pf2]);
                    if (ang1 == Math.PI / 2)
                    {
                        ang1 = 0;
                    }
                    else
                    {
                        ang1 = 1 / Math.Tan(ang1);
                    }
                    if (ang2 == Math.PI / 2)
                    {
                        ang2 = 0;
                    }
                    else
                    {
                        ang2 = 1 / Math.Tan(ang2);
                    }
                    double total = ang1 + ang2;
                    double t1    = Vector3d.Multiply(ps[pi1].n, (vs[pi1] - vs[pi2]));
                    double t2    = Vector3d.Multiply(ps[pi2].n, (vs[pi2] - vs[pi1]));
                    ps[pi1].KH += t1 * total;
                    ps[pi2].KH += t2 * total;
                    ////////////////
                }
            }
        }
예제 #3
0
        public Mesh Loop(Mesh x)
        {
            Mesh mesh = new Mesh();

            x.Faces.ConvertQuadsToTriangles();
            List <Point3d> pv = new List <Point3d>();
            List <Point3d> pe = new List <Point3d>();

            Rhino.Geometry.Collections.MeshTopologyVertexList vs = x.TopologyVertices;
            Rhino.Geometry.Collections.MeshTopologyEdgeList   el = x.TopologyEdges;
            for (int i = 0; i < el.Count; i++)
            {
                IndexPair pair  = el.GetTopologyVertices(i);
                Point3d   pe1   = (vs[pair.I] + vs[pair.J]);
                int[]     index = el.GetConnectedFaces(i);
                if (index.Length == 2)
                {
                    int[] index1 = vs.IndicesFromFace(index[0]);
                    int[] index2 = vs.IndicesFromFace(index[1]);
                    pe1 += vs[index1[0]] + vs[index1[1]] + vs[index1[2]];
                    pe1 += vs[index2[0]] + vs[index2[1]] + vs[index2[2]];
                    pe1 /= 8.0;
                }
                else
                {
                    pe1 = pe1 / 2.0;
                }
                pe.Add(pe1);
            }
            for (int i = 0; i < vs.Count; i++)
            {
                int[]   index  = vs.ConnectedEdges(i);
                int[]   index2 = vs.ConnectedFaces(i);
                Point3d V      = vs[i];
                if (index.Length == index2.Length)
                {
                    Point3d R = new Point3d();
                    double  n = (double)index.Length;
                    double  u = Math.Pow(0.375 + 0.25 * Math.Cos(Math.PI * 2.0 / n), 2); u = (0.625 - u) / n;
                    for (int j = 0; j < index.Length; j++)
                    {
                        IndexPair pair = el.GetTopologyVertices(index[j]);
                        R += (vs[pair.I] + vs[pair.J] - V);
                    }
                    V = V * (1 - n * u) + R * u;
                }
                else
                {
                    Point3d R = new Point3d();
                    for (int j = 0; j < index.Length; j++)
                    {
                        if (el.GetConnectedFaces(index[j]).Length == 1)
                        {
                            IndexPair pair = el.GetTopologyVertices(index[j]);
                            R += vs[pair.I] + vs[pair.J];
                        }
                    }
                    V = R * 0.125f + V * 0.5;
                }
                pv.Add(V);
            }
            mesh.Vertices.AddVertices(pv);
            mesh.Vertices.AddVertices(pe);
            for (int i = 0; i < x.Faces.Count; i++)
            {
                int[] index = vs.IndicesFromFace(i);
                int   p1 = index[0]; int p2 = index[1]; int p3 = index[2];
                int   p12 = el.GetEdgeIndex(p1, p2) + pv.Count;
                int   p23 = el.GetEdgeIndex(p2, p3) + pv.Count;
                int   p31 = el.GetEdgeIndex(p3, p1) + pv.Count;
                mesh.Faces.AddFace(p1, p12, p31);
                mesh.Faces.AddFace(p31, p12, p23);
                mesh.Faces.AddFace(p3, p31, p23);
                mesh.Faces.AddFace(p2, p23, p12);
            }
            mesh.UnifyNormals();
            return(mesh);
        }