Beispiel #1
0
 internal static bool CanBeCracked(com.epl.geometry.EditShape shape)
 {
     for (int geometry = shape.GetFirstGeometry(); geometry != -1; geometry = shape.GetNextGeometry(geometry))
     {
         if (!com.epl.geometry.Geometry.IsMultiPath(shape.GetGeometryType(geometry)))
         {
             continue;
         }
         return(true);
     }
     return(false);
 }
        internal bool ClusterNonReciprocal_()
        {
            int point_count = m_shape.GetTotalPointCount();

            com.epl.geometry.Envelope2D env = m_shape.GetEnvelope2D();
            m_origin = env.GetLowerLeft();
            double dim     = System.Math.Max(env.GetHeight(), env.GetWidth());
            double mincell = dim / (com.epl.geometry.NumberUtils.IntMax() - 1);

            if (m_cell_size < mincell)
            {
                m_cell_size     = mincell;
                m_inv_cell_size = 1.0 / m_cell_size;
            }
            // This holds clusters.
            m_clusters = new com.epl.geometry.IndexMultiList();
            m_clusters.ReserveLists(m_shape.GetTotalPointCount() / 3 + 1);
            m_clusters.ReserveNodes(m_shape.GetTotalPointCount() / 3 + 1);
            m_hash_values  = m_shape.CreateUserIndex();
            m_new_clusters = m_shape.CreateUserIndex();
            // Make the hash table. It serves a purpose of fine grain grid.
            // Make it 25% larger than the 4 times point count to reduce the chance
            // of collision.
            // The 4 times comes from the fact that we check four neighbouring cells
            // in the grid for each point.
            m_hash_function = new com.epl.geometry.Clusterer.ClusterHashFunction(this, m_shape, m_origin, m_sqr_tolerance, m_inv_cell_size, m_hash_values);
            m_hash_table    = new com.epl.geometry.IndexHashTable(4 * point_count / 3, m_hash_function);
            m_hash_table.ReserveElements(m_shape.GetTotalPointCount());
            bool b_clustered = false;

            // Go through all vertices stored in the m_shape and put the handles of
            // the vertices into the clusters and the hash table.
            for (int geometry = m_shape.GetFirstGeometry(); geometry != -1; geometry = m_shape.GetNextGeometry(geometry))
            {
                for (int path = m_shape.GetFirstPath(geometry); path != -1; path = m_shape.GetNextPath(path))
                {
                    int vertex = m_shape.GetFirstVertex(path);
                    for (int index = 0, nindex = m_shape.GetPathSize(path); index < nindex; index++)
                    {
                        System.Diagnostics.Debug.Assert((vertex != -1));
                        int hash = m_hash_function.Calculate_hash_from_vertex(vertex);
                        m_shape.SetUserIndex(vertex, m_hash_values, hash);
                        m_hash_table.AddElement(vertex, hash);
                        // add cluster to the
                        // hash table
                        System.Diagnostics.Debug.Assert((m_shape.GetUserIndex(vertex, m_new_clusters) == -1));
                        vertex = m_shape.GetNextVertex(vertex);
                    }
                }
            }
            {
                // m_hash_table->dbg_print_bucket_histogram_();
                // scope for candidates array
                com.epl.geometry.AttributeStreamOfInt32 candidates = new com.epl.geometry.AttributeStreamOfInt32(0);
                candidates.Reserve(10);
                for (int geometry_1 = m_shape.GetFirstGeometry(); geometry_1 != -1; geometry_1 = m_shape.GetNextGeometry(geometry_1))
                {
                    for (int path = m_shape.GetFirstPath(geometry_1); path != -1; path = m_shape.GetNextPath(path))
                    {
                        int vertex = m_shape.GetFirstVertex(path);
                        for (int index = 0, nindex = m_shape.GetPathSize(path); index < nindex; index++)
                        {
                            if (m_shape.GetUserIndex(vertex, m_new_clusters) == com.epl.geometry.StridedIndexTypeCollection.ImpossibleIndex2())
                            {
                                vertex = m_shape.GetNextVertex(vertex);
                                continue;
                            }
                            // this vertex was merged with another
                            // cluster. It also was removed from the
                            // hash table.
                            int hash = m_shape.GetUserIndex(vertex, m_hash_values);
                            m_hash_table.DeleteElement(vertex, hash);
                            while (true)
                            {
                                CollectClusterCandidates_(vertex, candidates);
                                if (candidates.Size() == 0)
                                {
                                    // no candidate for
                                    // clustering has
                                    // been found for
                                    // the cluster_1.
                                    break;
                                }
                                bool clustered = false;
                                for (int candidate_index = 0, ncandidates = candidates.Size(); candidate_index < ncandidates; candidate_index++)
                                {
                                    int cluster_node = candidates.Get(candidate_index);
                                    int other_vertex = m_hash_table.GetElement(cluster_node);
                                    m_hash_table.DeleteNode(cluster_node);
                                    clustered |= MergeClusters_(vertex, other_vertex, candidate_index + 1 == ncandidates);
                                }
                                b_clustered |= clustered;
                                candidates.Clear(false);
                                // repeat search for the cluster candidates for
                                // cluster_1
                                if (!clustered)
                                {
                                    break;
                                }
                            }
                            // positions did not change
                            // m_shape->set_user_index(vertex, m_new_clusters,
                            // Strided_index_type_collection::impossible_index_2());
                            vertex = m_shape.GetNextVertex(vertex);
                        }
                    }
                }
            }
            if (b_clustered)
            {
                ApplyClusterPositions_();
            }
            m_hash_table    = null;
            m_hash_function = null;
            m_shape.RemoveUserIndex(m_hash_values);
            m_shape.RemoveUserIndex(m_new_clusters);
            // output_debug_printf("total: %d\n",m_shape->get_total_point_count());
            // output_debug_printf("clustered: %d\n",m_dbg_candidate_check_count);
            return(b_clustered);
        }
Beispiel #3
0
        private void _fixOrphanVertices()
        {
            int pathCount = 0;

            // clean any path info
            for (int node = m_sortedVertices.GetFirst(m_sortedVertices.GetFirstList()); node != -1; node = m_sortedVertices.GetNext(node))
            {
                int vertex = m_sortedVertices.GetData(node);
                m_shape.SetPathToVertex_(vertex, -1);
            }
            int geometrySize = 0;

            for (int path = m_shape.GetFirstPath(m_geometry); path != -1;)
            {
                int first = m_shape.GetFirstVertex(path);
                if (first == -1 || m_shape.GetPathFromVertex(first) != -1)
                {
                    int p = path;
                    path = m_shape.GetNextPath(path);
                    m_shape.RemovePathOnly_(p);
                    continue;
                }
                m_shape.SetPathToVertex_(first, path);
                int pathSize = 1;
                for (int vertex = m_shape.GetNextVertex(first); vertex != first; vertex = m_shape.GetNextVertex(vertex))
                {
                    m_shape.SetPathToVertex_(vertex, path);
                    pathSize++;
                }
                m_shape.SetRingAreaValid_(path, false);
                m_shape.SetPathSize_(path, pathSize);
                m_shape.SetLastVertex_(path, m_shape.GetPrevVertex(first));
                geometrySize += pathSize;
                pathCount++;
                path = m_shape.GetNextPath(path);
            }
            // Some vertices do not belong to any path. We have to create new path
            // objects for those.
            // Produce new paths for the orphan vertices.
            for (int node_1 = m_sortedVertices.GetFirst(m_sortedVertices.GetFirstList()); node_1 != -1; node_1 = m_sortedVertices.GetNext(node_1))
            {
                int vertex = m_sortedVertices.GetData(node_1);
                if (m_shape.GetPathFromVertex(vertex) != -1)
                {
                    continue;
                }
                int path_1 = m_shape.InsertClosedPath_(m_geometry, -1, vertex, vertex, null);
                geometrySize += m_shape.GetPathSize(path_1);
                pathCount++;
            }
            m_shape.SetGeometryPathCount_(m_geometry, pathCount);
            m_shape.SetGeometryVertexCount_(m_geometry, geometrySize);
            int totalPointCount = 0;

            for (int geometry = m_shape.GetFirstGeometry(); geometry != -1; geometry = m_shape.GetNextGeometry(geometry))
            {
                totalPointCount += m_shape.GetPointCount(geometry);
            }
            m_shape.SetTotalPointCount_(totalPointCount);
        }