示例#1
0
        public static IMesh Triangulate2DElements(IMesh mesh)
        {
            IMesh triangulated = new IMesh();

            foreach (ITopologicVertex v in mesh.Vertices)
            {
                triangulated.AddVertex(v.Key, new ITopologicVertex(v));
            }

            ISurfaceElement face;
            int             key = mesh.FindNextVertexKey();

            foreach (IElement e in mesh.Elements)
            {
                if (e.TopologicDimension == 2)
                {
                    if (e.VerticesCount == 3)
                    {
                        face = new ISurfaceElement(e.Vertices[0], e.Vertices[1], e.Vertices[2]);
                        triangulated.AddElement(face);
                    }
                    else if (e.VerticesCount == 4)
                    {
                        face = new ISurfaceElement(e.Vertices[0], e.Vertices[1], e.Vertices[3]);
                        triangulated.AddElement(face);
                        face = new ISurfaceElement(e.Vertices[3], e.Vertices[1], e.Vertices[2]);
                        triangulated.AddElement(face);
                    }
                    else
                    {
                        IPoint3D         pos = ISubdividor.ComputeAveragePosition(e.Vertices, mesh);
                        ITopologicVertex v   = new ITopologicVertex(pos.X, pos.Y, pos.Z, key);
                        triangulated.AddVertex(key, v);
                        for (int i = 1; i <= e.HalfFacetsCount; i++)
                        {
                            int[] hf;
                            e.GetHalfFacet(i, out hf);
                            face = new ISurfaceElement(hf[0], hf[1], key);
                            triangulated.AddElement(face);
                        }
                        key++;
                    }
                }
            }

            triangulated.BuildTopology();

            return(triangulated);
        }
示例#2
0
        public static IMesh ExtrudeTwoDimensionalElementsEdges(IMesh mesh, IEnumerable <int> eKeys, double length)
        {
            IMesh            dM = mesh.CleanCopy();
            ITopologicVertex v, vv;
            IVector3D        n;
            IElement         e, nE;
            int next_vKey = mesh.FindNextVertexKey();
            int next_eKey = mesh.FindNextElementKey();

            foreach (int eK in eKeys)
            {
                e = mesh.GetElementWithKey(eK);
                if (e.TopologicDimension == 2)
                {
                    List <int> vertices = new List <int>();
                    foreach (int vK in e.Vertices)
                    {
                        v  = mesh.GetVertexWithKey(vK);
                        n  = mesh.Topology.ComputeVertexNormal(vK);
                        vv = new ITopologicVertex(v.Position + n, next_vKey);
                        dM.AddVertex(next_vKey, vv);
                        vertices.Add(next_vKey);
                        next_vKey++;
                    }

                    int[]      hf;
                    List <int> temp;
                    int        next_i, prev_i;
                    for (int i = 1; i <= e.HalfFacetsCount; i++)
                    {
                        e.GetHalfFacet(i, out hf);
                        temp   = new List <int>(hf);
                        next_i = i;
                        if (i == e.HalfFacetsCount)
                        {
                            next_i = 0;
                        }
                        prev_i = i - 1;
                        temp.Add(vertices[next_i]);
                        temp.Add(vertices[prev_i]);

                        nE = new ISurfaceElement(temp.ToArray());
                        dM.AddElement(nE);
                    }
                }
            }

            dM.BuildTopology(true);
            return(dM);
        }
示例#3
0
        public static IMesh ExtrudeTwoDimensionalElements(IMesh mesh, IEnumerable <int> eKeys, double length)
        {
            IMesh            dM = mesh.CleanCopy();
            ITopologicVertex v, vv;
            IVector3D        n, pos;
            IElement         e, nE;
            int next_vKey = mesh.FindNextVertexKey();

            foreach (int eK in eKeys)
            {
                e = mesh.GetElementWithKey(eK);
                if (e.TopologicDimension == 2)
                {
                    dM.DeleteElement(eK, false);
                    nE = null;
                    mesh.Topology.ComputeTwoDimensionalElementNormal(eK, out n, out pos);
                    n *= length;
                    List <int> vertices = new List <int>(e.Vertices);

                    foreach (int vK in e.Vertices)
                    {
                        v  = mesh.GetVertexWithKey(vK);
                        vv = new ITopologicVertex(v.Position + n, next_vKey);
                        dM.AddVertex(next_vKey, vv);
                        vertices.Add(next_vKey);
                        next_vKey++;
                    }

                    if (vertices.Count == 8)
                    {
                        nE = new IHexahedronElement(vertices.ToArray());
                    }
                    else if (vertices.Count == 6)
                    {
                        nE = new IPrismElement(vertices.ToArray());
                    }

                    if (nE != null)
                    {
                        dM.AddElement(nE);
                    }
                }
            }

            dM.BuildTopology(true);
            return(dM);
        }
示例#4
0
        public IMesh BuildMesh()
        {
            IMesh   mesh = new IMesh();
            Boolean flag = BuildDataBase();

            if (flag)
            {
                mesh = new IMesh();
                mesh.AddRangeVertices(vertices.ToList());
                foreach (int[] f in faces)
                {
                    mesh.AddElement(new ISurfaceElement(f[0], f[1], f[2], f[3]));
                }

                mesh.BuildTopology();
            }

            return(mesh);
        }
示例#5
0
        public static IMesh DualMesh(IMesh mesh)
        {
            IMesh nM = new IMesh();

            // Face center points
            foreach (IElement e in mesh.Elements)
            {
                nM.AddVertex(e.Key, new ITopologicVertex(ISubdividor.ComputeAveragePosition(e.Vertices, mesh)));
            }

            int[]      data1, data2;
            PointCloud cloud  = new PointCloud();
            List <int> global = new List <int>();

            int vertexKey = nM.FindNextVertexKey();

            foreach (ITopologicVertex v in mesh.Vertices)
            {
                data1 = mesh.Topology.GetVertexIncidentElementsSorted(v.Key);
                if (!mesh.Topology.IsNakedVertex(v.Key))
                {
                    nM.AddElement(new ISurfaceElement(data1));
                }
                else
                {
                    List <int> local = new List <int>();

                    data2 = mesh.Topology.GetVertexAdjacentVerticesSorted(v.Key);
                    bool flag = false;

                    foreach (int vv in data2)
                    {
                        if (mesh.Topology.IsNakedEdge(vv, v.Key))
                        {
                            Point3d p   = ISubdividor.ComputeAveragePoint(new[] { vv, v.Key }, mesh);
                            int     idx = cloud.ClosestPoint(p);

                            if (idx == -1)
                            {
                                flag = true;
                            }
                            else
                            {
                                if (p.DistanceTo(cloud[idx].Location) > 0.01)
                                {
                                    flag = true;
                                }
                                else
                                {
                                    flag = false;
                                }
                            }

                            if (flag)
                            {
                                cloud.Add(p);
                                nM.AddVertex(vertexKey, new ITopologicVertex(p));
                                global.Add(vertexKey);
                                local.Add(vertexKey);
                                vertexKey++;
                            }
                            else
                            {
                                local.Add(global[idx]);
                            }
                        }
                    }

                    nM.AddVertex(vertexKey, new ITopologicVertex(v));
                    local.Insert(1, vertexKey);
                    local.AddRange(data1.Reverse());
                    vertexKey++;

                    nM.AddElement(new ISurfaceElement(local.ToArray()));
                }
            }

            nM.BuildTopology(true);

            return(nM);
        }
        public static IMesh CatmullClark(IMesh mesh)
        {
            IMesh sMesh = new IMesh();

            //Old vertices
            foreach (int vK in mesh.VerticesKeys)
            {
                sMesh.AddVertex(vK, new ITopologicVertex(ComputesCatmullClarkVertexPosition(mesh, vK)));
            }

            // Subidvision
            int key = mesh.FindNextVertexKey();

            int[]    hf;
            IElement element_sibling;
            int      elementID_sibling, halfFacetID_sibling;
            Boolean  visited;
            Dictionary <int, int[]> eVertex = new Dictionary <int, int[]>();
            Dictionary <int, int>   fVertex = new Dictionary <int, int>();

            IPoint3D pos;

            int count = mesh.ElementsKeys.Count;

            // Vertices
            foreach (int elementID in mesh.ElementsKeys)
            {
                IElement e = mesh.GetElementWithKey(elementID);

                //Add face vertex
                pos = ComputeAveragePosition(e.Vertices, mesh);
                sMesh.AddVertex(key, new ITopologicVertex(pos.X, pos.Y, pos.Z, key));
                fVertex.Add(elementID, key);
                key++;

                if (!e.Visited)
                {
                    if (e.TopologicDimension == 2)
                    {
                        if (!eVertex.ContainsKey(elementID))
                        {
                            eVertex.Add(elementID, new int[e.HalfFacetsCount]);
                        }

                        for (int halfFacetID = 1; halfFacetID <= e.HalfFacetsCount; halfFacetID++)
                        {
                            e.GetHalfFacet(halfFacetID, out hf);
                            visited = e.IsHalfFacetVisited(halfFacetID);

                            if (!visited)
                            {
                                e.RegisterHalfFacetVisit(halfFacetID);
                                e.GetHalfFacet(halfFacetID, out hf);
                                pos = ComputeAveragePosition(hf, mesh);
                                sMesh.AddVertex(key, new ITopologicVertex(pos.X, pos.Y, pos.Z, key));
                                eVertex[elementID][halfFacetID - 1] = key;

                                if (!e.IsNakedSiblingHalfFacet(halfFacetID))
                                {
                                    while (!visited)
                                    {
                                        e.RegisterHalfFacetVisit(halfFacetID);

                                        //Collect information of siblings
                                        elementID_sibling   = e.GetSiblingElementID(halfFacetID);
                                        halfFacetID_sibling = e.GetSiblingHalfFacetID(halfFacetID);
                                        element_sibling     = mesh.GetElementWithKey(elementID_sibling);

                                        visited = element_sibling.IsHalfFacetVisited(halfFacetID_sibling);

                                        halfFacetID = halfFacetID_sibling;
                                        e           = element_sibling;

                                        if (!eVertex.ContainsKey(elementID_sibling))
                                        {
                                            eVertex.Add(elementID_sibling, new int[e.HalfFacetsCount]);
                                        }
                                        eVertex[elementID_sibling][halfFacetID - 1] = key;
                                    }
                                }

                                key++;
                            }
                        }
                    }
                }
            }
            mesh.CleanElementsVisits();

            //Faces
            int prev;

            int[] data;
            foreach (int elementID in mesh.ElementsKeys)
            {
                IElement e = mesh.GetElementWithKey(elementID);

                if (e.TopologicDimension == 2)
                {
                    int[] eV = eVertex[elementID];
                    for (int i = 0; i < e.Vertices.Length; i++)
                    {
                        prev = i - 1;
                        if (prev < 0)
                        {
                            prev = e.Vertices.Length - 1;
                        }

                        data = new int[] { e.Vertices[i], eV[prev], fVertex[elementID], eV[i] };
                        ISurfaceElement face = new ISurfaceElement(data);
                        sMesh.AddElement(face);
                    }
                }
            }

            // Edge Vertex
            foreach (int eK in eVertex.Keys)
            {
                IElement e = mesh.GetElementWithKey(eK);
                for (int i = 1; i <= e.HalfFacetsCount; i++)
                {
                    int[] hf1;
                    e.GetHalfFacet(i, out hf1);
                    ITopologicVertex v1 = sMesh.GetVertexWithKey(eVertex[eK][i - 1]);
                    v1.Position = ComputeCatmullClarkEdgeVertexPosition(hf1, mesh);
                    sMesh.SetVertex(v1.Key, v1);
                }
            }

            //Build Mesh
            sMesh.BuildTopology();

            return(sMesh);
        }
示例#7
0
        public static IMesh Loop(IMesh mesh)
        {
            IMesh triMesh = IModifier.Triangulate2DElements(mesh);

            IMesh sMesh = new IMesh();

            //Old vertices
            foreach (int vK in triMesh.VerticesKeys)
            {
                sMesh.AddVertex(vK, new ITopologicVertex(ComputeLoopVertexPosition(triMesh, vK)));
            }

            // Subidvision
            int key = triMesh.FindNextVertexKey();

            int[]    hf;
            IElement element_sibling;
            int      elementID_sibling, halfFacetID_sibling;
            Boolean  visited;
            Dictionary <int, int[]> eVertex = new Dictionary <int, int[]>();

            // Vertices
            foreach (int elementID in triMesh.ElementsKeys)
            {
                IElement e = triMesh.GetElementWithKey(elementID);

                if (!e.Visited)
                {
                    if (e.TopologicDimension == 2)
                    {
                        if (!eVertex.ContainsKey(elementID))
                        {
                            eVertex.Add(elementID, new int[e.HalfFacetsCount]);
                        }

                        for (int halfFacetID = 1; halfFacetID <= e.HalfFacetsCount; halfFacetID++)
                        {
                            e.GetHalfFacet(halfFacetID, out hf);
                            visited = e.IsHalfFacetVisited(halfFacetID);

                            if (!visited)
                            {
                                e.RegisterHalfFacetVisit(halfFacetID);
                                e.GetHalfFacet(halfFacetID, out hf);
                                sMesh.AddVertex(key, new ITopologicVertex(ComputeAveragePosition(hf, triMesh)));
                                eVertex[elementID][halfFacetID - 1] = key;

                                if (!e.IsNakedSiblingHalfFacet(halfFacetID))
                                {
                                    while (!visited)
                                    {
                                        e.RegisterHalfFacetVisit(halfFacetID);

                                        //Collect information of siblings
                                        elementID_sibling   = e.GetSiblingElementID(halfFacetID);
                                        halfFacetID_sibling = e.GetSiblingHalfFacetID(halfFacetID);
                                        element_sibling     = triMesh.GetElementWithKey(elementID_sibling);

                                        visited = element_sibling.IsHalfFacetVisited(halfFacetID_sibling);

                                        halfFacetID = halfFacetID_sibling;
                                        e           = element_sibling;

                                        if (!eVertex.ContainsKey(elementID_sibling))
                                        {
                                            eVertex.Add(elementID_sibling, new int[e.HalfFacetsCount]);
                                        }
                                        eVertex[elementID_sibling][halfFacetID - 1] = key;
                                    }
                                }

                                key++;
                            }
                        }
                    }
                }
            }
            triMesh.CleanElementsVisits();

            //Faces
            int prev;

            foreach (int elementID in triMesh.ElementsKeys)
            {
                IElement e = triMesh.GetElementWithKey(elementID);

                if (e.TopologicDimension == 2)
                {
                    int[] eV = eVertex[elementID];
                    for (int i = 0; i < e.Vertices.Length; i++)
                    {
                        prev = i - 1;
                        if (prev < 0)
                        {
                            prev = e.Vertices.Length - 1;
                        }

                        sMesh.AddElement(new ISurfaceElement(new[] { eV[prev], e.Vertices[i], eV[i] }));
                    }
                    sMesh.AddElement(new ISurfaceElement(new[] { eV[0], eV[1], eV[2] }));
                }
            }

            // Edge Vertex
            foreach (int eK in eVertex.Keys)
            {
                IElement e = triMesh.GetElementWithKey(eK);
                for (int i = 1; i <= e.HalfFacetsCount; i++)
                {
                    e.GetHalfFacet(i, out hf);
                    int vK = eVertex[eK][i - 1];
                    sMesh.SetVertexPosition(vK, ComputeLoopEdgeVertexPosition(hf, triMesh));
                }
            }

            //Build Mesh
            sMesh.BuildTopology();

            return(sMesh);
        }
            public static HashSet <int> TryParseToIguanaElement(int elementType, long[] nodes, int nodes_per_element, int number_of_elements, ref HashSet <int> parsedNodes, ref IMesh mesh)
            {
                if (IsElementImplemented(elementType))
                {
                    for (int j = 0; j < number_of_elements; j++)
                    {
                        int[] eD = new int[nodes_per_element];

                        IElement e = null;

                        for (int k = 0; k < nodes_per_element; k++)
                        {
                            eD[k] = (int)nodes[j * nodes_per_element + k];
                            parsedNodes.Add(eD[k]);
                        }

                        switch (elementType)
                        {
                        //1st-order Triangle Face
                        case 2:
                            e = new ISurfaceElement(eD);
                            break;

                        //1st-order Quadrangle Face
                        case 3:
                            e = new ISurfaceElement(eD);
                            break;

                        //2nd-order 6-node triangle
                        case 9:
                            e = new ISurfaceElement.HighOrder.ITriangle6(eD);
                            break;

                        //2nd-order 9-node quadrangle
                        case 10:
                            e = new ISurfaceElement.HighOrder.IQuadrangle9(eD);
                            break;

                        //2nd-order 8-node quadrangle
                        case 16:
                            e = new ISurfaceElement.HighOrder.IQuadrangle8(eD);
                            break;

                        //3rd-order 9-node incomplete triangle
                        case 20:
                            e = new ISurfaceElement.HighOrder.ITriangle9(eD);
                            break;

                        //4th-order 12-node incomplete triangle
                        case 22:
                            e = new ISurfaceElement.HighOrder.ITriangle12(eD);
                            break;

                        //5th-order 15-node incomplete triangle
                        case 24:
                            e = new ISurfaceElement.HighOrder.ITriangle15(eD);
                            break;

                        //2nd-order 10-node tetrahedron
                        case 11:
                            e = new ITetrahedronElement.HighOrder.ITetrahedron10(eD);
                            break;

                        //1s-order 4-node tetrahedron element
                        case 4:
                            e = new ITetrahedronElement(eD);
                            break;

                        //2n-order 13-node pyramid
                        case 19:
                            e = new IPyramidElement.HighOrder.IPyramid13(eD);
                            break;

                        //1st-order 5-node pyramid element
                        case 7:
                            e = new IPyramidElement(eD);
                            break;

                        //1st-order 6-node prism element
                        case 6:
                            e = new IPrismElement(eD);
                            break;

                        //2nd-order 15-node prism
                        case 18:
                            e = new IPrismElement.HighOrder.IPrism15(eD);
                            break;

                        //1st-order 8-node hexahedron element
                        case 5:
                            e = new IHexahedronElement(eD);
                            break;

                        //2nd-order 20-node hexahedron
                        case 17:
                            e = new IHexahedronElement.HighOrder.IHexahedron20(eD);
                            break;
                        }

                        if (e != null)
                        {
                            mesh.AddElement(e);
                        }
                    }
                }
                return(parsedNodes);
            }