P2trCDT* p2tr_cdt_new (P2tCDT *cdt) { P2tTrianglePtrArray cdt_tris = p2t_cdt_get_triangles (cdt); GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equal); P2trCDT *rmesh = g_slice_new (P2trCDT); gint i, j; rmesh->mesh = p2tr_mesh_new (); rmesh->outline = p2tr_pslg_new (); /* First iteration over the CDT - create all the points */ for (i = 0; i < cdt_tris->len; i++) { P2tTriangle *cdt_tri = triangle_index (cdt_tris, i); for (j = 0; j < 3; j++) { P2tPoint *cdt_pt = p2t_triangle_get_point(cdt_tri, j); P2trPoint *new_pt = g_hash_table_lookup (point_map, cdt_pt); if (new_pt == NULL) { new_pt = p2tr_point_new2 (cdt_pt->x, cdt_pt->y); g_hash_table_insert (point_map, cdt_pt, new_pt); } } } /* Second iteration over the CDT - create all the edges and find the * outline */ for (i = 0; i < cdt_tris->len; i++) { P2tTriangle *cdt_tri = triangle_index (cdt_tris, i); for (j = 0; j < 3; j++) { P2tPoint *start = p2t_triangle_get_point (cdt_tri, j); P2tPoint *end = p2t_triangle_get_point (cdt_tri, (j + 1) % 3); int edge_index = p2t_triangle_edge_index (cdt_tri, start, end); P2trPoint *start_new = g_hash_table_lookup (point_map, start); P2trPoint *end_new = g_hash_table_lookup (point_map, end); if (! p2tr_point_has_edge_to (start_new, end_new)) { gboolean constrained = cdt_tri->constrained_edge[edge_index]; P2trEdge *edge = p2tr_mesh_new_edge (rmesh->mesh, start_new, end_new, constrained); /* If the edge is constrained, we should add it to the * outline */ if (constrained) p2tr_pslg_add_new_line(rmesh->outline, &start_new->c, &end_new->c); /* We only wanted to create the edge now. We will use it * later */ p2tr_edge_unref (edge); } } } /* Third iteration over the CDT - create all the triangles */ for (i = 0; i < cdt_tris->len; i++) { P2tTriangle *cdt_tri = triangle_index (cdt_tris, i); P2trPoint *pt1 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 0)); P2trPoint *pt2 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 1)); P2trPoint *pt3 = g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 2)); P2trTriangle *new_tri = p2tr_mesh_new_triangle (rmesh->mesh, p2tr_point_get_edge_to(pt1, pt2), p2tr_point_get_edge_to(pt2, pt3), p2tr_point_get_edge_to(pt3, pt1)); /* We won't do any usage of the triangle, so just unref it */ p2tr_triangle_unref (new_tri); } return rmesh; }
P2trCDT* p2tr_cdt_new (P2tCDT *cdt) { P2tTrianglePtrArray cdt_tris = p2t_cdt_get_triangles (cdt); GHashTable *point_map = g_hash_table_new (g_direct_hash, g_direct_equal); P2trCDT *rmesh = g_slice_new (P2trCDT); GHashTableIter iter; P2trPoint *pt_iter = NULL; P2trVEdgeSet *new_edges = p2tr_vedge_set_new (); guint i, j; rmesh->mesh = p2tr_mesh_new (); rmesh->outline = p2tr_pslg_new (); /* First iteration over the CDT - create all the points */ for (i = 0; i < cdt_tris->len; i++) { P2tTriangle *cdt_tri = triangle_index (cdt_tris, i); for (j = 0; j < 3; j++) { P2tPoint *cdt_pt = p2t_triangle_get_point(cdt_tri, j); P2trPoint *new_pt = (P2trPoint*) g_hash_table_lookup (point_map, cdt_pt); if (new_pt == NULL) { new_pt = p2tr_mesh_new_point2 (rmesh->mesh, cdt_pt->x, cdt_pt->y); g_hash_table_insert (point_map, cdt_pt, new_pt); } } } /* Second iteration over the CDT - create all the edges and find the * outline */ for (i = 0; i < cdt_tris->len; i++) { P2tTriangle *cdt_tri = triangle_index (cdt_tris, i); for (j = 0; j < 3; j++) { P2tPoint *start = p2t_triangle_get_point (cdt_tri, j); P2tPoint *end = p2t_triangle_get_point (cdt_tri, (j + 1) % 3); int edge_index = p2t_triangle_edge_index (cdt_tri, start, end); P2trPoint *start_new = (P2trPoint*) g_hash_table_lookup (point_map, start); P2trPoint *end_new = (P2trPoint*) g_hash_table_lookup (point_map, end); if (! p2tr_point_has_edge_to (start_new, end_new)) { gboolean constrained = cdt_tri->constrained_edge[edge_index] || cdt_tri->neighbors_[edge_index] == NULL; P2trEdge *edge = p2tr_mesh_new_edge (rmesh->mesh, start_new, end_new, constrained); /* If the edge is constrained, we should add it to the * outline */ if (constrained) p2tr_pslg_add_new_line(rmesh->outline, &start_new->c, &end_new->c); /* We only wanted to create the edge now. We will use it * later */ p2tr_vedge_set_add (new_edges, edge); } } } /* Third iteration over the CDT - create all the triangles */ for (i = 0; i < cdt_tris->len; i++) { P2tTriangle *cdt_tri = triangle_index (cdt_tris, i); P2trPoint *pt1 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 0)); P2trPoint *pt2 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 1)); P2trPoint *pt3 = (P2trPoint*) g_hash_table_lookup (point_map, p2t_triangle_get_point (cdt_tri, 2)); P2trTriangle *new_tri = p2tr_mesh_new_triangle (rmesh->mesh, p2tr_point_get_edge_to(pt1, pt2, FALSE), p2tr_point_get_edge_to(pt2, pt3, FALSE), p2tr_point_get_edge_to(pt3, pt1, FALSE)); /* We won't do any usage of the triangle, so just unref it */ p2tr_triangle_unref (new_tri); } /* And do an extra flip fix */ p2tr_cdt_flip_fix (rmesh, new_edges); p2tr_vedge_set_free (new_edges); /* Now finally unref the points we added into the map */ g_hash_table_iter_init (&iter, point_map); while (g_hash_table_iter_next (&iter, NULL, (gpointer*)&pt_iter)) p2tr_point_unref (pt_iter); g_hash_table_destroy (point_map); return rmesh; }