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); }
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); }