static void polyedge_beauty_cost_update_single( const float (*coords)[2], const unsigned int (*tris)[3], const struct PolyEdge *edges, struct PolyEdge *e, Heap *eheap, HeapNode **eheap_table) { const unsigned int i = (unsigned int)(e - edges); if (eheap_table[i]) { BLI_heap_remove(eheap, eheap_table[i]); eheap_table[i] = NULL; } { /* recalculate edge */ const float cost = polyedge_rotate_beauty_calc(coords, tris, e); /* We can get cases where both choices generate very small negative costs, which leads to infinite loop. * Anyway, costs above that are not worth recomputing, maybe we could even optimize it to a smaller limit? * See T43578. */ if (cost < -FLT_EPSILON) { eheap_table[i] = BLI_heap_insert(eheap, cost, e); } else { eheap_table[i] = NULL; } } }
/* recalc an edge in the heap (surrounding geometry has changed) */ static void bm_edge_update_beauty_cost_single( BMEdge *e, Heap *eheap, HeapNode **eheap_table, GSet **edge_state_arr, /* only for testing the edge is in the array */ const BMEdge **edge_array, const int edge_array_len, const short flag, const short method) { if (edge_in_array(e, edge_array, edge_array_len)) { const int i = BM_elem_index_get(e); GSet *e_state_set = edge_state_arr[i]; if (eheap_table[i]) { BLI_heap_remove(eheap, eheap_table[i]); eheap_table[i] = NULL; } /* check if we can add it back */ BLI_assert(BM_edge_is_manifold(e) == true); /* check we're not moving back into a state we have been in before */ if (e_state_set != NULL) { EdRotState e_state_alt; erot_state_alternate(e, &e_state_alt); if (BLI_gset_haskey(e_state_set, (void *)&e_state_alt)) { // printf(" skipping, we already have this state\n"); return; } } { /* recalculate edge */ const float cost = bm_edge_calc_rotate_beauty(e, flag, method); if (cost < 0.0f) { eheap_table[i] = BLI_heap_insert(eheap, cost, e); } else { eheap_table[i] = NULL; } } } }
static void colorband_init_from_table_rgba_resample( ColorBand *coba, const float (*array)[4], const int array_len, bool filter_samples) { BLI_assert(array_len >= 2); const float eps_2x = ((1.0f / 255.0f) + 1e-6f); struct ColorResampleElem *c, *carr = MEM_mallocN(sizeof(*carr) * array_len, __func__); int carr_len = array_len; c = carr; { const float step_size = 1.0f / (float)(array_len - 1); for (int i = 0; i < array_len; i++, c++) { copy_v4_v4(carr[i].rgba, array[i]); c->next = c + 1; c->prev = c - 1; c->pos = i * step_size; } } carr[0].prev = NULL; carr[array_len - 1].next = NULL; /* -2 to remove endpoints. */ Heap *heap = BLI_heap_new_ex(array_len - 2); c = carr; for (int i = 0; i < array_len; i++, c++) { float cost = color_sample_remove_cost(c); if (cost != -1.0f) { c->node = BLI_heap_insert(heap, cost, c); } else { c->node = NULL; } } while ((carr_len > 1 && !BLI_heap_is_empty(heap)) && ((carr_len >= MAXCOLORBAND) || (BLI_heap_node_value(BLI_heap_top(heap)) <= eps_2x))) { c = BLI_heap_pop_min(heap); struct ColorResampleElem *c_next = c->next, *c_prev = c->prev; c_prev->next = c_next; c_next->prev = c_prev; /* Clear data (not essential, avoid confusion). */ c->prev = c->next = NULL; c->node = NULL; /* Update adjacent */ for (int i = 0; i < 2; i++) { struct ColorResampleElem *c_other = i ? c_next : c_prev; if (c_other->node != NULL) { const float cost = color_sample_remove_cost(c_other); if (cost != -1.0) { BLI_heap_node_value_update(heap, c_other->node, cost); } else { BLI_heap_remove(heap, c_other->node); c_other->node = NULL; } } } carr_len -= 1; } BLI_heap_free(heap, NULL); /* First member is never removed. */ int i = 0; BLI_assert(carr_len < MAXCOLORBAND); if (filter_samples == false) { for (c = carr; c != NULL; c = c->next, i++) { copy_v4_v4(&coba->data[i].r, c->rgba); coba->data[i].pos = c->pos; coba->data[i].cur = i; } } else { for (c = carr; c != NULL; c = c->next, i++) { const int steps_prev = c->prev ? (c - c->prev) - 1 : 0; const int steps_next = c->next ? (c->next - c) - 1 : 0; if (steps_prev == 0 && steps_next == 0) { copy_v4_v4(&coba->data[i].r, c->rgba); } else { float rgba[4]; float rgba_accum = 1; copy_v4_v4(rgba, c->rgba); if (steps_prev) { const float step_size = 1.0 / (float)(steps_prev + 1); int j = steps_prev; for (struct ColorResampleElem *c_other = c - 1; c_other != c->prev; c_other--, j--) { const float step_pos = (float)j * step_size; BLI_assert(step_pos > 0.0f && step_pos < 1.0f); const float f = filter_gauss(step_pos); madd_v4_v4fl(rgba, c_other->rgba, f); rgba_accum += f; } } if (steps_next) { const float step_size = 1.0 / (float)(steps_next + 1); int j = steps_next; for (struct ColorResampleElem *c_other = c + 1; c_other != c->next; c_other++, j--) { const float step_pos = (float)j * step_size; BLI_assert(step_pos > 0.0f && step_pos < 1.0f); const float f = filter_gauss(step_pos); madd_v4_v4fl(rgba, c_other->rgba, f); rgba_accum += f; } } mul_v4_v4fl(&coba->data[i].r, rgba, 1.0f / rgba_accum); } coba->data[i].pos = c->pos; coba->data[i].cur = i; } } BLI_assert(i == carr_len); coba->tot = i; coba->cur = 0; MEM_freeN(carr); }