Example #1
0
        public static TetgenMesh ToTetgenMesh(this Mesh m)
        {
            Mesh M = m.DuplicateMesh();

            M.Faces.ConvertQuadsToTriangles();
            M.UnifyNormals();

            TetgenMesh tm = new TetgenMesh();

            tm.Vertices    = new double[M.Vertices.Count * 3];
            tm.FaceIndices = new int[M.Faces.Count * 3];
            tm.FaceSizes   = new int[M.Faces.Count];

            for (int i = 0; i < M.Vertices.Count; ++i)
            {
                tm.Vertices[i * 3]     = M.Vertices[i].X;
                tm.Vertices[i * 3 + 1] = M.Vertices[i].Y;
                tm.Vertices[i * 3 + 2] = M.Vertices[i].Z;
            }

            for (int i = 0; i < M.Faces.Count; ++i)
            {
                tm.FaceSizes[i]           = 3;
                tm.FaceIndices[i * 3]     = M.Faces[i].A;
                tm.FaceIndices[i * 3 + 1] = M.Faces[i].B;
                tm.FaceIndices[i * 3 + 2] = M.Faces[i].C;
            }

            return(tm);
        }
Example #2
0
        public static TetgenMesh ToTetgenMesh(this Mesh m)
        {
            Mesh M = m.DuplicateMesh();

            //M.Faces.ConvertQuadsToTriangles();
            M.UnifyNormals();

            TetgenMesh tm = new TetgenMesh();

            tm.Vertices = new double[M.Vertices.Count * 3];

            var FaceIndexCount = 0;

            tm.FaceSizes = new int[M.Faces.Count];

            for (int i = 0; i < M.Faces.Count; ++i)
            {
                int fsize = M.Faces[i].IsQuad ? 4 : 3;

                FaceIndexCount += fsize;
                tm.FaceSizes[i] = fsize;
            }

            tm.FaceIndices = new int[FaceIndexCount];

            for (int i = 0; i < M.Vertices.Count; ++i)
            {
                tm.Vertices[i * 3]     = M.Vertices[i].X;
                tm.Vertices[i * 3 + 1] = M.Vertices[i].Y;
                tm.Vertices[i * 3 + 2] = M.Vertices[i].Z;
            }

            int fi = 0;

            for (int i = 0; i < M.Faces.Count; ++i)
            {
                tm.FaceIndices[fi] = M.Faces[i].A; fi++;
                tm.FaceIndices[fi] = M.Faces[i].B; fi++;
                tm.FaceIndices[fi] = M.Faces[i].C; fi++;

                if (M.Faces[i].IsQuad)
                {
                    tm.FaceIndices[fi] = M.Faces[i].D;
                    fi++;
                }
            }


            return(tm);
        }
Example #3
0
        public static List <Point3d> ToPointList(this TetgenMesh tm)
        {
            List <Point3d> points = new List <Point3d>();

            for (int i = 0; i < tm.Vertices.Length; i += 3)
            {
                points.Add(new Point3d(
                               tm.Vertices[i],
                               tm.Vertices[i + 1],
                               tm.Vertices[i + 2]
                               ));
            }

            return(points);
        }
Example #4
0
        public static Mesh[] TetraToRhinoMesh(this TetgenMesh tm)
        {
            List <Point3d> points = new List <Point3d>();

            for (int i = 0; i < tm.Vertices.Length; i += 3)
            {
                points.Add(new Point3d(
                               tm.Vertices[i],
                               tm.Vertices[i + 1],
                               tm.Vertices[i + 2]
                               ));
            }

            Mesh[] tetra = new Mesh[tm.TetraIndices.Length / 4];

            for (int i = 0; i < tetra.Length; ++i)
            {
                int  ivert = i * 4;
                Mesh t     = new Mesh();
                t.Vertices.Add(points[tm.TetraIndices[ivert]]);
                t.Vertices.Add(points[tm.TetraIndices[ivert + 1]]);
                t.Vertices.Add(points[tm.TetraIndices[ivert + 2]]);
                t.Vertices.Add(points[tm.TetraIndices[ivert + 3]]);

                t.Faces.AddFace(0, 1, 2);
                t.Faces.AddFace(1, 2, 3);
                t.Faces.AddFace(2, 3, 0);
                t.Faces.AddFace(3, 0, 1);

                t.FaceNormals.ComputeFaceNormals();
                t.Normals.ComputeNormals();
                t.UnifyNormals();

                tetra[i] = t;
            }
            return(tetra);
        }
Example #5
0
        public static Mesh ToRhinoMesh(this TetgenMesh tm)
        {
            Mesh m = new Mesh();


            for (int i = 0; i < tm.Vertices.Length; i += 3)
            {
                m.Vertices.Add(
                    tm.Vertices[i],
                    tm.Vertices[i + 1],
                    tm.Vertices[i + 2]
                    );
            }

            for (int i = 0; i < tm.FaceIndices.Length; i += 3)
            {
                m.Faces.AddFace(
                    tm.FaceIndices[i],
                    tm.FaceIndices[i + 1],
                    tm.FaceIndices[i + 2]
                    );
            }

            m.Vertices.CullUnused();

            m.FaceNormals.ComputeFaceNormals();
            m.Normals.ComputeNormals();
            m.UnifyNormals();

            if (m.SolidOrientation() <= 0)
            {
                m.Flip(true, true, true);
            }

            return(m);
        }
Example #6
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Mesh> meshes = new List <Mesh>();

            if (!DA.GetDataList("Mesh", meshes))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No input mesh specified.");
                return;
            }

            int flags = 1;

            DA.GetData("Flags", ref flags);

            double minratio = 2.0;

            DA.GetData("MinRatio", ref minratio);
            if (minratio <= 1.0)
            {
                minratio = 1.1;
            }

            double maxvolume = 2.0;

            DA.GetData("MaxVolume", ref maxvolume);

            int steiner = 0;

            DA.GetData("Steiner", ref steiner);

            int coarsen = 0;

            DA.GetData("Coarsen", ref coarsen);

            DataTree <int>      indices    = new DataTree <int>();
            DataTree <GH_Mesh>  meshes_out = new DataTree <GH_Mesh>();
            DataTree <GH_Point> points_out = new DataTree <GH_Point>();

            var face_indices  = new DataTree <int>();
            var verts_indices = new DataTree <int>();

            int     N, index = 0;
            GH_Path path;

            for (int i = 0; i < meshes.Count; ++i)
            {
                if (maxvolume > 0)
                {
                    var vmp = VolumeMassProperties.Compute(meshes[i]);
                    maxvolume = Math.Max(maxvolume, vmp.Volume / 100000); // Safety so as not to end up with too many elements...
                }

                TetgenSharp.TetgenBehaviour b = new TetgenSharp.TetgenBehaviour();
                b.quality          = 1;
                b.plc              = 1;
                b.minratio         = minratio;
                b.coarsen          = coarsen;
                b.maxvolume        = maxvolume;
                b.supsteiner_level = steiner;

                TetgenMesh             tin = TetgenRC.ExtensionMethods.ToTetgenMesh(meshes[i]);
                TetgenSharp.TetgenMesh tm  = TetgenSharp.TetRhino.Tetrahedralize(tin, b);
                //path = new GH_Path(i);

                if (tm == null)
                {
                    this.Message = "Failed.";
                    return;
                }

                switch (flags)
                {
                case (0):
                    meshes_out.AddRange(TetgenRC.ExtensionMethods.TetraToRhinoMesh(tm).Select(x => new GH_Mesh(x)), new GH_Path(i, 0));
                    break;

                case (1):
                    meshes_out.Add(new GH_Mesh(TetgenRC.ExtensionMethods.ToRhinoMesh(tm)), new GH_Path(i, 0));
                    break;

                case (2):

                    N = tm.TetraIndices.Length / 4;
                    for (int j = 0; j < N; ++j)
                    {
                        path  = new GH_Path(i, j);
                        index = j * 4;

                        indices.Add(tm.TetraIndices[index], path);
                        indices.Add(tm.TetraIndices[index + 1], path);
                        indices.Add(tm.TetraIndices[index + 2], path);
                        indices.Add(tm.TetraIndices[index + 3], path);
                    }

                    N = tm.FaceSizes.Length;

                    int fi = 0;
                    for (int j = 0; j < N; ++j)
                    {
                        var fpath = new GH_Path(i, j);
                        for (int k = 0; k < tm.FaceSizes[j]; ++k)
                        {
                            face_indices.Add(tm.FaceIndices[fi], fpath);
                            fi++;
                        }
                    }

                    points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0));
                    break;

                case (3):
                    N = tm.EdgeIndices.Length / 2;
                    for (int j = 0; j < N; ++j)
                    {
                        path  = new GH_Path(i, j);
                        index = j * 2;

                        indices.Add(tm.EdgeIndices[index], path);
                        indices.Add(tm.EdgeIndices[index + 1], path);
                    }

                    points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0));
                    break;

                default:
                    break;
                }
            }

            DA.SetDataTree(MeshOutIndex, meshes_out);
            DA.SetDataTree(IndicesOutIndex, indices);
            DA.SetDataTree(PointsOutIndex, points_out);
            DA.SetDataTree(FacesOutIndex, face_indices);
        }
Example #7
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Mesh> meshes = new List <Mesh>();

            if (!DA.GetDataList("Mesh", meshes))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No input mesh specified.");
                return;
            }

            int flags = 1;

            DA.GetData("Flags", ref flags);

            double minratio = 2.0;

            DA.GetData("MinRatio", ref minratio);
            if (minratio <= 1.0)
            {
                minratio = 1.1;
            }

            TetgenSharp.TetgenBehaviour b = new TetgenSharp.TetgenBehaviour();
            b.quality  = 1;
            b.plc      = 1;
            b.minratio = minratio;
            b.coarsen  = 1;

            DataTree <int>      indices    = new DataTree <int>();
            DataTree <GH_Mesh>  meshes_out = new DataTree <GH_Mesh>();
            DataTree <GH_Point> points_out = new DataTree <GH_Point>();

            int     N, index = 0;
            GH_Path path;

            for (int i = 0; i < meshes.Count; ++i)
            {
                TetgenMesh             tin = TetgenRC.ExtensionMethods.ToTetgenMesh(meshes[i]);
                TetgenSharp.TetgenMesh tm  = TetgenSharp.TetRhino.Tetrahedralize(tin, b);
                //path = new GH_Path(i);

                switch (flags)
                {
                case (0):
                    meshes_out.AddRange(TetgenRC.ExtensionMethods.TetraToRhinoMesh(tm).Select(x => new GH_Mesh(x)), new GH_Path(i, 0));
                    break;

                case (1):
                    meshes_out.Add(new GH_Mesh(TetgenRC.ExtensionMethods.ToRhinoMesh(tm)), new GH_Path(i, 0));
                    break;

                case (2):
                    N = tm.TetraIndices.Length / 4;
                    for (int j = 0; j < N; ++j)
                    {
                        path  = new GH_Path(i, j);
                        index = j * 4;

                        indices.Add(tm.TetraIndices[index], path);
                        indices.Add(tm.TetraIndices[index + 1], path);
                        indices.Add(tm.TetraIndices[index + 2], path);
                        indices.Add(tm.TetraIndices[index + 3], path);
                    }
                    points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0));
                    break;

                case (3):
                    N = tm.EdgeIndices.Length / 2;
                    for (int j = 0; j < N; ++j)
                    {
                        path  = new GH_Path(i, j);
                        index = j * 2;

                        indices.Add(tm.EdgeIndices[index], path);
                        indices.Add(tm.EdgeIndices[index + 1], path);
                    }

                    points_out.AddRange(TetgenRC.ExtensionMethods.ToPointList(tm).Select(x => new GH_Point(x)), new GH_Path(i, 0));
                    break;

                default:
                    break;
                }
            }

            DA.SetDataTree(MeshOutIndex, meshes_out);
            DA.SetDataTree(IndicesOutIndex, indices);
            DA.SetDataTree(PointsOutIndex, points_out);
        }
Example #8
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh mesh = new Mesh();

            if (!DA.GetData("Mesh", ref mesh))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No input mesh specified.");
                return;
            }

            int flags = 1;

            DA.GetData("Flags", ref flags);

            double minratio = 2.0;

            DA.GetData("MinRatio", ref minratio);
            if (minratio <= 1.0)
            {
                minratio = 1.1;
            }

            TetgenSharp.TetgenBehaviour b = new TetgenSharp.TetgenBehaviour();
            b.quality  = 1;
            b.plc      = 1;
            b.minratio = minratio;
            b.coarsen  = 1;

            TetgenMesh tin = TetgenRC.ExtensionMethods.ToTetgenMesh(mesh);

            TetgenSharp.TetgenMesh tm = TetgenSharp.TetRhino.Tetrahedralize(tin, b);

            DataTree <int> indices;
            int            N, index = 0;
            GH_Path        path;

            switch (flags)
            {
            case (0):
                DA.SetDataList("Mesh", TetgenRC.ExtensionMethods.TetraToRhinoMesh(tm).Select(x => new GH_Mesh(x)));
                break;

            case (1):
                DA.SetDataList("Mesh", new GH_Mesh[] { new GH_Mesh(TetgenRC.ExtensionMethods.ToRhinoMesh(tm)) });
                break;

            case (2):
                indices = new DataTree <int>();
                N       = tm.TetraIndices.Length / 4;
                DA.SetData("Length", N);                                                            //Ajout BH
                for (int i = 0; i < N; ++i)
                {
                    path  = new GH_Path(i);
                    index = i * 4;

                    indices.Add(tm.TetraIndices[index], path);
                    indices.Add(tm.TetraIndices[index + 1], path);
                    indices.Add(tm.TetraIndices[index + 2], path);
                    indices.Add(tm.TetraIndices[index + 3], path);
                }

                DA.SetDataTree(1, indices);
                DA.SetDataList("Points", TetgenRC.ExtensionMethods.ToPointList(tm));
                break;

            case (3):
                indices = new DataTree <int>();
                N       = tm.EdgeIndices.Length / 2;
                for (int i = 0; i < N; ++i)
                {
                    path  = new GH_Path(i);
                    index = i * 2;

                    indices.Add(tm.EdgeIndices[index], path);
                    indices.Add(tm.EdgeIndices[index + 1], path);
                }

                DA.SetDataTree(1, indices);
                DA.SetDataList("Points", TetgenRC.ExtensionMethods.ToPointList(tm));
                break;

            default:
                break;
            }
        }