code cleanup: move beauty fill calculation into its own function and some style cleanup

This commit is contained in:
2013-03-30 09:57:35 +00:00
parent b1f4e2b4db
commit 20376f3337
6 changed files with 138 additions and 124 deletions

View File

@@ -142,6 +142,103 @@ static void bm_edge_tag_rotated(BMEdge *e)
BM_elem_flag_enable(l->prev->e, BM_ELEM_TAG);
}
/* -------------------------------------------------------------------- */
/* Calculate the improvement of rotating the edge */
/**
* \return a positive value means the edge can be rotated.
*/
static float bm_edge_calc_rotate_beauty(const BMEdge *e)
{
/* not a loop (only to be able to break out) */
do {
float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
/* first get the 2d values */
{
const float *v1, *v2, *v3, *v4;
bool is_zero_a, is_zero_b;
float no[3];
float axis_mat[3][3];
v1 = e->l->prev->v->co; /* first face co */
v2 = e->l->v->co; /* e->v1 or e->v2*/
v3 = e->l->radial_next->prev->v->co; /* second face co */
v4 = e->l->next->v->co; /* e->v1 or e->v2*/
if (UNLIKELY(v1 == v3)) {
// printf("This should never happen, but does sometimes!\n");
break;
}
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
BLI_assert((ELEM3(v1, v2, v3, v4) == false) &&
(ELEM3(v2, v1, v3, v4) == false) &&
(ELEM3(v3, v1, v2, v4) == false) &&
(ELEM3(v4, v1, v2, v3) == false));
is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON;
is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON;
if (LIKELY(is_zero_a == false && is_zero_b == false)) {
float no_a[3], no_b[3];
normal_tri_v3(no_a, v2, v3, v4); /* a */
normal_tri_v3(no_b, v2, v4, v1); /* b */
add_v3_v3v3(no, no_a, no_b);
if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) {
break;
}
}
else if (is_zero_a == false) {
normal_tri_v3(no, v2, v3, v4); /* a */
}
else if (is_zero_b == false) {
normal_tri_v3(no, v2, v4, v1); /* b */
}
else {
/* both zero area, no useful normal can be calculated */
break;
}
// { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);}
axis_dominant_v3_to_m3(axis_mat, no);
mul_v2_m3v3(v1_xy, axis_mat, v1);
mul_v2_m3v3(v2_xy, axis_mat, v2);
mul_v2_m3v3(v3_xy, axis_mat, v3);
mul_v2_m3v3(v4_xy, axis_mat, v4);
}
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
/* testing rule:
* the area divided by the total edge lengths
*/
len1 = len_v2v2(v1_xy, v2_xy);
len2 = len_v2v2(v2_xy, v3_xy);
len3 = len_v2v2(v3_xy, v4_xy);
len4 = len_v2v2(v4_xy, v1_xy);
len5 = len_v2v2(v1_xy, v3_xy);
len6 = len_v2v2(v2_xy, v4_xy);
opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy);
opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy);
fac1 = opp1 / (len1 + len2 + len5) + opp2 / (len3 + len4 + len5);
opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy);
opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy);
fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6);
return fac1 - fac2;
}
} while (false);
return -1.0f;
}
/* -------------------------------------------------------------------- */
/* Beautify Fill */
@@ -170,8 +267,6 @@ static void bm_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge
BMEdge *e = edge_array[i];
GHash *e_state_hash;
float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
BLI_assert(BM_edge_is_manifold(e) == true);
BLI_assert(BMO_elem_flag_test(bm, e->l->f, FACE_MARK) &&
BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK));
@@ -195,115 +290,36 @@ static void bm_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge
}
}
{
const float *v1, *v2, *v3, *v4;
bool is_zero_a, is_zero_b;
float no[3];
float axis_mat[3][3];
if (bm_edge_calc_rotate_beauty(e) > 0.0f) {
e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS);
if (LIKELY(e)) {
v1 = e->l->prev->v->co; /* first face co */
v2 = e->l->v->co; /* e->v1 or e->v2*/
v3 = e->l->radial_next->prev->v->co; /* second face co */
v4 = e->l->next->v->co; /* e->v1 or e->v2*/
if (UNLIKELY(v1 == v3)) {
// printf("This should never happen, but does sometimes!\n");
continue;
}
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
BLI_assert((ELEM3(v1, v2, v3, v4) == false) &&
(ELEM3(v2, v1, v3, v4) == false) &&
(ELEM3(v3, v1, v2, v4) == false) &&
(ELEM3(v4, v1, v2, v3) == false));
is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON;
is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON;
if (LIKELY(is_zero_a == false && is_zero_b == false)) {
float no_a[3], no_b[3];
normal_tri_v3(no_a, v2, v3, v4); /* a */
normal_tri_v3(no_b, v2, v4, v1); /* b */
add_v3_v3v3(no, no_a, no_b);
if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) {
continue;
/* add the new state into the hash so we don't move into this state again
* note: we could add the previous state too but this isn't essential)
* for avoiding eternal loops */
EdRotState *e_state = BLI_mempool_alloc(edge_state_pool);
erot_state_current(e, e_state);
if (UNLIKELY(e_state_hash == NULL)) {
edge_state_arr[i] = e_state_hash = erot_ghash_new(); /* store previous state */
}
}
else if (is_zero_a == false) {
normal_tri_v3(no, v2, v3, v4); /* a */
}
else if (is_zero_b == false) {
normal_tri_v3(no, v2, v4, v1); /* b */
}
else {
/* both zero area, no useful normal can be calculated */
continue;
}
// { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);}
axis_dominant_v3_to_m3(axis_mat, no);
mul_v2_m3v3(v1_xy, axis_mat, v1);
mul_v2_m3v3(v2_xy, axis_mat, v2);
mul_v2_m3v3(v3_xy, axis_mat, v3);
mul_v2_m3v3(v4_xy, axis_mat, v4);
}
// printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f);
if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) {
float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2;
/* testing rule:
* the area divided by the total edge lengths
*/
len1 = len_v2v2(v1_xy, v2_xy);
len2 = len_v2v2(v2_xy, v3_xy);
len3 = len_v2v2(v3_xy, v4_xy);
len4 = len_v2v2(v4_xy, v1_xy);
len5 = len_v2v2(v1_xy, v3_xy);
len6 = len_v2v2(v2_xy, v4_xy);
opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy);
opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy);
fac1 = opp1 / (len1 + len2 + len5) + opp2 / (len3 + len4 + len5);
opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy);
opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy);
fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6);
if (fac1 > fac2) {
e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS);
if (LIKELY(e)) {
/* add the new state into the hash so we don't move into this state again
* note: we could add the previous state too but this isn't essential)
* for avoiding eternal loops */
EdRotState *e_state = BLI_mempool_alloc(edge_state_pool);
erot_state_current(e, e_state);
if (UNLIKELY(e_state_hash == NULL)) {
edge_state_arr[i] = e_state_hash = erot_ghash_new(); /* store previous state */
}
BLI_assert(BLI_ghash_haskey(e_state_hash, (void *)e_state) == false);
BLI_ghash_insert(e_state_hash, e_state, NULL);
BLI_assert(BLI_ghash_haskey(e_state_hash, (void *)e_state) == false);
BLI_ghash_insert(e_state_hash, e_state, NULL);
// printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2));
// printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2));
/* maintain the index array */
edge_array[i] = e;
BM_elem_index_set(e, i);
/* maintain the index array */
edge_array[i] = e;
BM_elem_index_set(e, i);
/* tag other edges so we know to check them again */
bm_edge_tag_rotated(e);
/* tag other edges so we know to check them again */
bm_edge_tag_rotated(e);
/* update flags */
BMO_elem_flag_enable(bm, e, ELE_NEW);
BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW);
BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW);
is_breaked = false;
}
/* update flags */
BMO_elem_flag_enable(bm, e, ELE_NEW);
BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW);
BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW);
is_breaked = false;
}
}
}

View File

@@ -101,11 +101,11 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
{
BMIter iter, liter;
BMVert *v, *v2;
BMEdge *e, *e2, **edges = NULL;
BMEdge *e, *e_new, **edges = NULL;
BLI_array_declare(edges);
BMLoop *l, *l2, **loops = NULL;
BMLoop *l, *l_new, **loops = NULL;
BLI_array_declare(loops);
BMFace *f, *f2;
BMFace *f, *f_new;
int a, b;
BMOpSlot *slot_targetmap = BMO_slot_get(op->slots_in, "targetmap");
@@ -182,10 +182,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
}
e2 = v != v2 ? BM_edge_exists(v, v2) : NULL;
if (e2) {
e_new = v != v2 ? BM_edge_exists(v, v2) : NULL;
if (e_new) {
for (b = 0; b < a; b++) {
if (edges[b] == e2) {
if (edges[b] == e_new) {
break;
}
}
@@ -196,7 +196,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
BLI_array_grow_one(edges);
BLI_array_grow_one(loops);
edges[a] = e2;
edges[a] = e_new;
loops[a] = l;
a++;
@@ -215,14 +215,14 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op)
v2 = BMO_slot_map_elem_get(slot_targetmap, v2);
}
f2 = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE);
if (f2 && (f2 != f)) {
BM_elem_attrs_copy(bm, bm, f, f2);
f_new = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE);
if (f_new && (f_new != f)) {
BM_elem_attrs_copy(bm, bm, f, f_new);
a = 0;
BM_ITER_ELEM (l, &liter, f2, BM_LOOPS_OF_FACE) {
l2 = loops[a];
BM_elem_attrs_copy(bm, bm, l2, l);
BM_ITER_ELEM (l, &liter, f_new, BM_LOOPS_OF_FACE) {
l_new = loops[a];
BM_elem_attrs_copy(bm, bm, l_new, l);
a++;
}

View File

@@ -1314,7 +1314,7 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect)
glShadeModel(GL_SMOOTH);
gluSphere(qobj, 100.0, 32, 24);
glShadeModel(GL_FLAT);
gluDeleteQuadric(qobj);
gluDeleteQuadric(qobj);
if (use_displist) {
glEndList();

View File

@@ -442,7 +442,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
quad.ymax = aim[1] + ups->anchored_size;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush)*zoom;
const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
quad.xmin = x - radius;
quad.ymin = y - radius;
quad.xmax = x + radius;
@@ -540,7 +540,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
translation[1] = y;
outline_alpha = 0.5;
outline_col = brush->add_col;
final_radius = BKE_brush_size_get(scene, brush)*zoomx;
final_radius = BKE_brush_size_get(scene, brush) * zoomx;
if (brush->flag & BRUSH_RAKE)
/* here, translation contains the mouse coordinates. */

View File

@@ -156,8 +156,7 @@ static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush)
static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, int size)
{
if ((painter->cache.flt != flt) || (painter->cache.size != size))
{
if ((painter->cache.flt != flt) || (painter->cache.size != size)) {
if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
painter->cache.ibuf = painter->cache.maskibuf = NULL;

View File

@@ -174,8 +174,7 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
ups->pixel_radius *= stroke->cached_pressure;
}
if (paint_supports_dynamic_tex_coords(brush, mode))
{
if (paint_supports_dynamic_tex_coords(brush, mode)) {
if (((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) ||
(brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)) &&
!(brush->flag & BRUSH_RAKE))