Пример #1
0
        public void CloseMesh(List <Line> lines, Edge <T> firstCutEdge)
        {
            MeshCell <T> cell = firstCutEdge.Cell;

            //Divide this cell
            //================================================================
            //NewVertices
            Vertex[] verticesOfNewRidgeBoundary = new Vertex[lines.Count + 2];
            verticesOfNewRidgeBoundary[0] = firstCutEdge.End;
            verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1] = Vertices[cell.IntersectionVertex];
            verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 2] = lines[0].start;
            int ID = AddVertex(lines[0].start);

            //Add Vertices of lines
            for (int i = 2; i < verticesOfNewRidgeBoundary.Length - 1; ++i)
            {
                verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i] = lines[i - 1].end;
                ID = AddVertex(verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i]);
            }
            //New Ridges
            Edge <T>[]   newRidges;
            Edge <T>[]   newNeighborRidges;
            MeshCell <T> newCell = new MeshCell <T>();

            AddCell(newCell);
            CreateEdge(verticesOfNewRidgeBoundary, cell, newCell, out newRidges, out newNeighborRidges);
            InsertEdgesAndVertices(newRidges, newNeighborRidges);
        }
Пример #2
0
        static void MoveNodesTowardsCellCenter <T>(IReadOnlyList <MeshCell <T> > Cells, ref int FirstCellNode_indice)
            where T : IMesherNode, new()
        {
            //Mark inside nodes
            //Use Original Nodes List and update. Use LinkedList?! Only iterate and cut some nodes, or insert
            //Let's give it a try!
            for (int i = 0; i < Cells.Count; ++i)
            {
                MeshCell <T> cell            = Cells[i];
                double       relaxValue      = 0.1;
                Vector       CenterOfGravity = new Vector(0, 0);
                foreach (Vertex vertex in cell.Vertices)
                {
                    CenterOfGravity += vertex.Position;
                }
                CenterOfGravity.Scale(1.0 / cell.Vertices.Length);
                CenterOfGravity = CenterOfGravity * relaxValue + new Vector(cell.Node.Position) * (1 - relaxValue);

                cell.Node.Position = CenterOfGravity;
                if (cell.ID == FirstCellNode_indice)
                {
                    FirstCellNode_indice = i;
                }
            }
        }
Пример #3
0
        public (MeshCell <T>, IEnumerator <Edge <T> >) getNeighborFromEdgeNeighbor(Edge <T> edge)
        {
            MeshCell <T>            newCell   = getNeighbour(edge);
            AfterCutRidgeEnumerator ridgeEnum = new AfterCutRidgeEnumerator(newCell.Edges, edge);

            return(newCell, ridgeEnum);
        }
Пример #4
0
        public void CreateEdge(Vertex[] vertices, MeshCell <T> cell, MeshCell <T> neighborCell, out Edge <T>[] ridges, out Edge <T>[] twinEdges)
        {
            int count = vertices.Length - 1;

            ridges    = new Edge <T> [count];
            twinEdges = new Edge <T> [count];
            for (int i = 0; i < count; ++i)
            {
                Edge <T> ridge = new Edge <T>
                {
                    Start = vertices[i],
                    End   = vertices[i + 1],
                    Cell  = cell
                };
                Edge <T> twinRidge = new Edge <T>
                {
                    Start      = vertices[i + 1],
                    End        = vertices[i],
                    Twin       = ridge,
                    Cell       = neighborCell,
                    IsBoundary = true
                };
                ridge.Twin = twinRidge;
                ridges[i]  = ridge;
                twinEdges[count - 1 - i] = twinRidge;
            }
        }
Пример #5
0
        public void VertexCut(Edge <T> edge, double alphaCut)
        {
            MeshCell <T> cell         = edge.Cell;
            Vertex       newOldVertex = edge.End;

            cell.IntersectionVertex = newOldVertex.ID;
            cell = edge.Twin.Cell;
            cell.IntersectionVertex = newOldVertex.ID;
        }
Пример #6
0
 public static MeshCell <T>[] Clone <T>(IList <MeshCell <T> > cells)
     where T : ILocatable, new()
 {
     MeshCell <T>[] clones = new MeshCell <T> [cells.Count];
     for (int i = 0; i < cells.Count; ++i)
     {
         clones[i] = Clone(cells[i]);
     }
     return(clones);
 }
Пример #7
0
        static Vector VertexMean <T>(MeshCell <T> cell)
        {
            Vector centerOfGravity = new Vector(0, 0);

            foreach (Vertex vertex in cell.Vertices)
            {
                centerOfGravity += vertex.Position;
            }
            centerOfGravity.Scale(1.0 / cell.Vertices.Length);
            return(centerOfGravity);
        }
Пример #8
0
        protected List <MeshCell <T> > SetCellTypesOnSameSideOfBoundary(MeshCell <T> startingCell, MeshCellType type, ref List <MeshCell <T> > cells)
        {
            List <MeshCell <T> > sameSideCells = new List <MeshCell <T> >();

            foreach (MeshCell <T> cell in CellsOnSameSideOfBoundary_Iterative(startingCell))
            {
                cell.type = type;
                sameSideCells.Add(cell);
            }
            return(sameSideCells);
        }
Пример #9
0
 static void MoveNodesTowardsCellCenter <T>(IReadOnlyList <MeshCell <T> > cells)
     where T : ILocatable
 {
     for (int i = 0; i < cells.Count; ++i)
     {
         MeshCell <T> cell            = cells[i];
         Vector       centerOfGravity = CenterOf(cell);
         double       relaxValue      = 0.3;
         centerOfGravity    = centerOfGravity * relaxValue + new Vector(cell.Node.Position) * (1 - relaxValue);
         cell.Node.Position = centerOfGravity;
     }
 }
Пример #10
0
        public static MeshCell <T> Clone <T>(MeshCell <T> cell)
            where T : ILocatable, new()
        {
            MeshCell <T> clone = new MeshCell <T>()
            {
                Node     = Clone(cell.Node),
                Type     = cell.Type,
                ID       = cell.ID,
                Vertices = Clone((IList <Vertex>)cell.Vertices),
                Edges    = Clone <T>(cell.Edges)
            };

            FuseEdgeVertices(clone.Edges, clone.Vertices);
            return(clone);
        }
Пример #11
0
        /// <summary>
        /// Enumerates the cells inside the boundary of this mesh.
        /// Recursion produces Stack overflow, when to many cells in mesh.
        /// </summary>
        /// <param name="cell">
        /// Enumeration starts with this cell and then return its neighbors and so on.
        /// </param>
        /// <returns></returns>
        static IEnumerable <MeshCell <T> > RecursiveYieldConnectedCells(MeshCell <T> cell, HashSet <int> visited)
        {
            visited.Add(cell.ID);
            yield return(cell);

            foreach (Edge <T> edge in cell.Edges)
            {
                Edge <T> newRidge = edge.Twin;
                if (!visited.Contains(newRidge.Cell.ID) && !newRidge.IsBoundary)
                {
                    foreach (MeshCell <T> neighbor in RecursiveYieldConnectedCells(newRidge.Cell, visited))
                    {
                        yield return(neighbor);
                    }
                }
            }
        }
Пример #12
0
        static Vector CenterOf <T>(MeshCell <T> cell)
        {
            Vector centerOfGravity = new Vector(0, 0);
            Vector root            = cell.Vertices[0].Position;
            double cellArea        = 0;

            for (int i = 1; i < cell.Vertices.Length - 1; ++i)
            {
                Vector a    = cell.Vertices[i].Position;
                Vector b    = cell.Vertices[i + 1].Position;
                double area = AreaOfTriangle(root, a, b);
                centerOfGravity += (root + a + b) / 3 * area;
                cellArea        += area;
            }
            centerOfGravity.Scale(1.0 / cellArea);
            return(centerOfGravity);
        }
Пример #13
0
        private IEnumerable <MeshCell <T> > YieldConnectedCells(MeshCell <T> cell, BitArray visited)
        {
            visited[cell.ID] = true;
            yield return(cell);

            foreach (Edge <T> edge in cell.Edges)
            {
                Edge <T> newRidge = edge.Twin;
                if (!visited[newRidge.Cell.ID] && !newRidge.IsBoundary)
                {
                    foreach (MeshCell <T> neighbor in YieldConnectedCells(newRidge.Cell, visited))
                    {
                        yield return(neighbor);
                    }
                }
            }
        }
Пример #14
0
        public Edge <T> SubdivideWithoutNewVertex(Edge <T> edge, List <Line> lines)
        {
            MeshCell <T>            cell       = edge.Cell;
            Vertex                  cutVertex  = edge.End;
            IEnumerator <Edge <T> > neighEdges = getConnectedRidgeEnum(edge);

            while (neighEdges.MoveNext())
            {
                MeshCell <T> neighbor = neighEdges.Current.Cell;
                if (neighbor.ID != cell.ID)
                {
                    neighbor.IntersectionVertex = cutVertex.ID;
                }
            }
            //Divide this cell
            //================================================================
            Vertex[] verticesOfNewEdgeBoundary = new Vertex[lines.Count + 2];
            verticesOfNewEdgeBoundary[0] = cutVertex;
            verticesOfNewEdgeBoundary[verticesOfNewEdgeBoundary.Length - 1] = Vertices[cell.IntersectionVertex];
            //Add Vertices of lines
            for (int i = 1; i < verticesOfNewEdgeBoundary.Length - 1; ++i)
            {
                verticesOfNewEdgeBoundary[verticesOfNewEdgeBoundary.Length - 1 - i] = lines[i - 1].end;
                AddVertex(verticesOfNewEdgeBoundary[verticesOfNewEdgeBoundary.Length - 1 - i]);
            }
            //New Ridges
            Edge <T>[]   newEdges;
            Edge <T>[]   newNeighborEdges;
            MeshCell <T> newCell = new MeshCell <T>();

            AddCell(newCell);
            CreateEdge(verticesOfNewEdgeBoundary, cell, newCell, out newEdges, out newNeighborEdges);
            //Link Ridges to old neighbors
            InsertEdgesAndVertices(newEdges, newNeighborEdges);


            //dOnE, DoNe!
            return(edge);
        }
Пример #15
0
        /// <summary>
        /// Enumerates the cells inside the boundary of this mesh.
        /// </summary>
        /// <param name="cell">
        /// Enumeration starts with this cell and then return its neighbors and so on.
        /// </param>
        /// <returns></returns>
        static IEnumerable <MeshCell <T> > IterativeYieldConnectedCells(MeshCell <T> cell, HashSet <int> visited)
        {
            Queue <MeshCell <T> > cells = new Queue <MeshCell <T> >();

            cells.Enqueue(cell);
            visited.Add(cell.ID);
            while (cells.Count > 0)
            {
                MeshCell <T> current = cells.Dequeue();
                yield return(current);

                foreach (Edge <T> edge in current.Edges)
                {
                    Edge <T> newEdge = edge.Twin;
                    if (newEdge != null && !newEdge.IsBoundary && !visited.Contains(newEdge.Cell.ID))
                    {
                        cells.Enqueue(newEdge.Cell);
                        visited.Add(newEdge.Cell.ID);
                    }
                }
            }
        }
Пример #16
0
        public Edge <T> Subdivide(Edge <T> edge, List <Line> lines, double alpha)
        {
            MeshCell <T> cell = edge.Cell;
            //Divide Ridge and update Ridge Arrays
            //-------------------------------------
            Vertex newVertex = DivideEdge(edge, alpha, out Edge <T> newRidge);

            edge.Twin.Cell.IntersectionVertex = newVertex.ID;
            //cell.IntersectionVertex = newVertex.ID;

            //Divide this cell
            //================================================================
            //NewVertices
            Vertex[] verticesOfNewRidgeBoundary = new Vertex[lines.Count + 2];
            verticesOfNewRidgeBoundary[0] = newVertex;
            verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1] = Vertices[cell.IntersectionVertex];
            //Add Vertices of lines
            for (int i = 1; i < verticesOfNewRidgeBoundary.Length - 1; ++i)
            {
                verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i] = lines[i - 1].end;
                int ID = AddVertex(verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i]);
            }
            //New Ridges
            Edge <T>[]   newEdges;
            Edge <T>[]   newNeighborEdges;
            MeshCell <T> newCell = new MeshCell <T> {
                Node = new T()
            };

            newCell.Node.Position = cell.Node.Position;
            AddCell(newCell);
            CreateEdge(verticesOfNewRidgeBoundary, cell, newCell, out newEdges, out newNeighborEdges);
            //Link Ridges to old neighbors
            InsertEdgesAndVertices(newEdges, newNeighborEdges);

            //dOnE, DoNe!
            return(edge);
        }
Пример #17
0
        public void InsertEdgesAndVertices(params Edge <T>[] additionalEdges)
        {
            MeshCell <T> cell = additionalEdges[0].Cell;
            int          countAdditionalRidges = additionalEdges.Length;

            Edge <T>[] newRidges      = new Edge <T> [cell.Edges.Length + countAdditionalRidges];
            bool       notInsertedYet = true;

            for (int i = 0; i < cell.Edges.Length; ++i)
            {
                if (notInsertedYet)
                {
                    newRidges[i] = cell.Edges[i];
                }
                else
                {
                    newRidges[i + countAdditionalRidges] = cell.Edges[i];
                }
                if (notInsertedYet && (additionalEdges[0].Start.ID == cell.Edges[i].End.ID))
                {
                    for (int k = 0; k < countAdditionalRidges; ++k)
                    {
                        newRidges[i + k + 1] = additionalEdges[k];
                    }

                    notInsertedYet = false;
                }
            }
            cell.Edges = newRidges;

            Vertex[] newVertices = new Vertex[cell.Vertices.Length + countAdditionalRidges];
            for (int i = 0; i < cell.Edges.Length; ++i)
            {
                newVertices[i] = newRidges[i].Start;
            }
            cell.Vertices = newVertices;
        }
Пример #18
0
        /// <summary>
        /// Enumerates the cells inside the boundary of this mesh.
        /// </summary>
        /// <param name="cell">
        /// Enumeration starts with this cell and then return its neighbors and so on.
        /// </param>
        /// <returns></returns>
        public IEnumerable <MeshCell <T> > CellsOnSameSideOfBoundary_Iterative(MeshCell <T> cell)
        {
            BitArray visited = new BitArray(Cells.Count);
            LinkedList <MeshCell <T> > cells = new LinkedList <MeshCell <T> >();

            cells.AddFirst(cell);
            visited[cell.ID] = true;
            while (cells.Count > 0)
            {
                MeshCell <T> current = cells.First.Value;
                yield return(current);

                cells.RemoveFirst();
                foreach (Edge <T> edge in current.Edges)
                {
                    Edge <T> newEdge = edge.Twin;
                    if (!visited[newEdge.Cell.ID] && !newEdge.IsBoundary)
                    {
                        cells.AddLast(newEdge.Cell);
                        visited[newEdge.Cell.ID] = true;
                    }
                }
            }
        }
Пример #19
0
 protected int AddCell(MeshCell <T> cell)
 {
     return(mesh.AddCell(cell));
 }
Пример #20
0
        /// <summary>
        /// Enumerates the cells inside the boundary of this mesh.
        /// Recursion produces Stack overflow, when to many cells in mesh.
        /// </summary>
        /// <param name="cell">
        /// Enumeration starts with this cell and then return its neighbors and so on.
        /// </param>
        /// <returns></returns>
        public IEnumerable <MeshCell <T> > CellsOnSameSideOfBoundary_Recursive(MeshCell <T> cell)
        {
            BitArray visited = new BitArray(Cells.Count);

            return(YieldConnectedCells(cell, visited));
        }
Пример #21
0
 public int AddCell(MeshCell <T> cell)
 {
     cell.ID = Cells.Count;
     Cells.Add(cell);
     return(cell.ID);
 }
Пример #22
0
        public void InsertEdgesAndVertices(Edge <T>[] newEdge, Edge <T>[] newNeighborEdges)
        {
            MeshCell <T> cell           = newEdge[0].Cell;
            MeshCell <T> emptyNeighCell = newNeighborEdges[0].Cell;

            Edge <T>[] oldRidges = cell.Edges;

            List <Edge <T> > cellRidges           = null;
            List <Edge <T> > emptyNeighCellRidges = null;
            List <Edge <T> > workerA         = new List <Edge <T> >(newEdge.Length);
            List <Edge <T> > workerB         = new List <Edge <T> >(newEdge.Length);
            bool             workerAIsActive = true;
            List <Edge <T> > tmp             = workerA;

            //Add new Ridges
            for (int i = 0; i < oldRidges.Length; ++i)
            {
                Edge <T> activeR = oldRidges[i];
                if (activeR.Start.ID == newEdge[0].Start.ID)
                {
                    cellRidges = tmp;
                    for (int j = 0; j < newEdge.Length; ++j)
                    {
                        cellRidges.Add(newEdge[j]);
                    }
                    tmp             = workerAIsActive ? workerB : workerA;
                    workerAIsActive = !workerAIsActive;
                }
                if (activeR.Start.ID == newNeighborEdges[0].Start.ID)
                {
                    emptyNeighCellRidges = tmp;
                    for (int j = 0; j < newNeighborEdges.Length; ++j)
                    {
                        emptyNeighCellRidges.Add(newNeighborEdges[j]);
                    }

                    tmp             = workerAIsActive ? workerB : workerA;
                    workerAIsActive = !workerAIsActive;
                }
                tmp.Add(activeR);
            }

            cell.Edges           = cellRidges.ToArray();
            emptyNeighCell.Edges = emptyNeighCellRidges.ToArray();

            //Update AllRidges
            for (int i = 0; i < cell.Edges.Length; ++i)
            {
                cell.Edges[i].Cell = cell;
            }
            for (int i = 0; i < emptyNeighCell.Edges.Length; ++i)
            {
                emptyNeighCell.Edges[i].Cell = emptyNeighCell;
            }

            //Vertices
            Vertex[] newVertices = new Vertex[cell.Edges.Length];
            for (int i = 0; i < cell.Edges.Length; ++i)
            {
                newVertices[i] = cell.Edges[i].Start;
            }
            cell.Vertices = newVertices;

            Vertex[] newNeighVertices = new Vertex[emptyNeighCell.Edges.Length];
            for (int i = 0; i < emptyNeighCell.Edges.Length; ++i)
            {
                newNeighVertices[i] = emptyNeighCell.Edges[i].Start;
            }
            emptyNeighCell.Vertices = newNeighVertices;
        }
Пример #23
0
        public static IEnumerable <MeshCell <T> > GetInsideCells(MeshCell <T> cell)
        {
            HashSet <int> visited = new HashSet <int>();

            return(IterativeYieldConnectedCells(cell, visited));
        }
Пример #24
0
 Domain <T> CreateMeshFrom(IList <T> nodes, MeshCell <T> firstCorner)
 {
     return(CreateMeshFrom(nodes, firstCorner.ID));
 }
Пример #25
0
 public Domain <T> Generate(IList <T> nodes, MeshCell <T> firstCorner)
 {
     return(Generate(nodes, firstCorner.ID));
 }