Пример #1
0
            public SubMeshes Process()
            {
                // Create a stack with an initial capacity matching Sqrt(#elmts), which will approximately match for
                // a square mesh with quads.
                _stack = new Stack <int>((int)System.Math.Sqrt(_meshData.NumberOfElements));

                SubMeshes subMeshes = new SubMeshes();

                subMeshes.SubMeshInfos = new List <SubMeshInfo>();
                int subMeshId = 0;

                ElmtSubMesh = new int[_meshData.NumberOfElements];
                for (int i = 0; i < _meshData.NumberOfElements; i++)
                {
                    if (ElmtSubMesh[i] == 0)
                    {
                        subMeshId++;
                        int subMeshElmtCount = BFSVisit(i, subMeshId);
                        subMeshes.SubMeshInfos.Add(new SubMeshInfo()
                        {
                            SubMeshId = subMeshId, NumberOfElments = subMeshElmtCount
                        });
                    }
                }

                subMeshes.ElmtSubMesh = ElmtSubMesh;
                return(subMeshes);
            }
Пример #2
0
        /// <summary>
        /// Find connected sub meshes.
        /// </summary>
        public static SubMeshes FindConnectedSubMeshes(this CMeshData meshData)
        {
            // We need faces information for each element.
            meshData.BuildFaces(true);

            BFSSubMesher subMesher = new BFSSubMesher(meshData);
            SubMeshes    subMeshes = subMesher.Process();

            // Sort such that the sub mesh with most element is first in the list
            subMeshes.SubMeshInfos.Sort((smi1, smi2) => - smi1.NumberOfElments.CompareTo(smi2.NumberOfElments));
            return(subMeshes);
        }
Пример #3
0
        /// <summary>
        /// Build boundary polygon. Returns either a <see cref="Polygon"/> or <see cref="MultiPolygon"/>
        /// depending on whether the mesh is fully connected or consist of independent parts.
        /// <para>
        /// To always return a <see cref="MultiPolygon"/>, set the <paramref name="alwaysMultiPolygon"/> to true.
        /// </para>
        /// </summary>
        private static Geometry BuildBoundaryGeometry(CMeshData mesh, List <CMeshFace> boundaryFaces, bool alwaysMultiPolygon)
        {
            // There will be one polygon for each connected sub mesh, in case there is more than one.

            //System.Diagnostics.Stopwatch timer = MeshExtensions.StartTimer();
            // Find all connected sub meshes.
            SubMeshes subMeshes = mesh.FindConnectedSubMeshes();
            //timer.ReportAndRestart("FindConnectedSubMeshes " + subMeshes.NumberOfSubMeshes);

            BoundarySegmentsBuilder bsb = new BoundarySegmentsBuilder(mesh);

            if (subMeshes.NumberOfSubMeshes == 1)
            {
                Polygon boundaryPoly = BuildSubMeshBoundaryGeometry(mesh, bsb, boundaryFaces);
                if (!alwaysMultiPolygon)
                {
                    return(boundaryPoly);
                }
                MultiPolygon multiPolygon = new MultiPolygon(new Polygon[] { boundaryPoly });
                return(multiPolygon);
            }

            else // More than one sub-mesh - make a Polygon for each sub mesh
            {
                // Find boundary faces for each sub mesh
                List <List <CMeshFace> > subMeshesBoundaryFaces = new List <List <CMeshFace> >(subMeshes.NumberOfSubMeshes);
                for (int i = 0; i < subMeshes.NumberOfSubMeshes; i++)
                {
                    subMeshesBoundaryFaces.Add(new List <CMeshFace>());
                }
                for (int i = 0; i < boundaryFaces.Count; i++)
                {
                    CMeshFace bcFace    = boundaryFaces[i];
                    int       subMeshId = subMeshes.ElmtSubMesh[bcFace.LeftElement.Index];
                    // subMeshId's starts from 1
                    subMeshesBoundaryFaces[subMeshId - 1].Add(bcFace);
                }

                // Make boundary polygon for each sub mesh - ordered as in SubMeshInfos to get largest parts first
                List <Polygon> polygons = new List <Polygon>(subMeshes.NumberOfSubMeshes);
                foreach (SubMeshInfo subMeshInfo in subMeshes.SubMeshInfos)
                {
                    List <CMeshFace> subMeshBoundaryFaces = subMeshesBoundaryFaces[subMeshInfo.SubMeshId - 1];
                    Polygon          subMeshBoundaryPoly  = BuildSubMeshBoundaryGeometry(mesh, bsb, subMeshBoundaryFaces);
                    polygons.Add(subMeshBoundaryPoly);
                }

                MultiPolygon multiPoly = new MultiPolygon(polygons.ToArray());
                return(multiPoly);
            }
        }