[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [60210] trunk/blender/source/blender/bmesh : fix [#36211] bridge edge loops joining vertecies that are far away
Campbell Barton
ideasman42 at gmail.com
Wed Sep 18 01:23:33 CEST 2013
Revision: 60210
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=60210
Author: campbellbarton
Date: 2013-09-17 23:23:32 +0000 (Tue, 17 Sep 2013)
Log Message:
-----------
fix [#36211] bridge edge loops joining vertecies that are far away
for bridge use a different beautify method when edge loops have non-matching loop count (simple face-angle comparison).
Modified Paths:
--------------
trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
trunk/blender/source/blender/bmesh/operators/bmo_beautify.c
trunk/blender/source/blender/bmesh/operators/bmo_bridge.c
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2013-09-17 22:48:08 UTC (rev 60209)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2013-09-17 23:23:32 UTC (rev 60210)
@@ -1580,6 +1580,7 @@
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
{"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
+ {"method", BMO_OP_SLOT_INT}, /* method to define what is beautiful */
{{'\0'}},
},
/* slots_out */
Modified: trunk/blender/source/blender/bmesh/operators/bmo_beautify.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_beautify.c 2013-09-17 22:48:08 UTC (rev 60209)
+++ trunk/blender/source/blender/bmesh/operators/bmo_beautify.c 2013-09-17 23:23:32 UTC (rev 60210)
@@ -43,6 +43,8 @@
#include "bmesh.h"
#include "intern/bmesh_operators_private.h"
+#include "BLI_strict_flags.h"
+
// #define DEBUG_TIME
#ifdef DEBUG_TIME
@@ -134,7 +136,8 @@
/**
* \return a negative value means the edge can be rotated.
*/
-static float bm_edge_calc_rotate_beauty(const BMEdge *e, const int flag)
+static float bm_edge_calc_rotate_beauty__area(
+ const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
/* not a loop (only to be able to break out) */
do {
@@ -142,28 +145,10 @@
/* 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 (flag & VERT_RESTRICT_TAG) {
- BMVert *v_a = e->l->prev->v, *v_b = e->l->radial_next->prev->v;
- if (BM_elem_flag_test(v_a, BM_ELEM_TAG) == BM_elem_flag_test(v_b, BM_ELEM_TAG)) {
- break;
- }
- }
-
- 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) &&
@@ -244,12 +229,74 @@
return FLT_MAX;
}
+static float bm_edge_calc_rotate_beauty__angle(
+ const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+{
+ /* not a loop (only to be able to break out) */
+ do {
+ float no_a[3], no_b[3];
+ float angle_24, angle_13;
+
+ /* edge (2-4), current state */
+ normal_tri_v3(no_a, v2, v3, v4);
+ normal_tri_v3(no_b, v2, v4, v1);
+ angle_24 = angle_normalized_v3v3(no_a, no_b);
+
+ /* edge (1-3), new state */
+ /* only check new state for degenerate outcome */
+ if ((normal_tri_v3(no_a, v1, v2, v3) == 0.0f) ||
+ (normal_tri_v3(no_b, v1, v3, v4) == 0.0f))
+ {
+ break;
+ }
+ angle_13 = angle_normalized_v3v3(no_a, no_b);
+
+ return angle_13 - angle_24;
+ } while (false);
+
+ return FLT_MAX;
+}
+
+static float bm_edge_calc_rotate_beauty(const BMEdge *e, const short flag, const short method)
+{
+ /* not a loop (only to be able to break out) */
+ do {
+ const float *v1, *v2, *v3, *v4;
+
+ 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 (flag & VERT_RESTRICT_TAG) {
+ BMVert *v_a = e->l->prev->v, *v_b = e->l->radial_next->prev->v;
+ if (BM_elem_flag_test(v_a, BM_ELEM_TAG) == BM_elem_flag_test(v_b, BM_ELEM_TAG)) {
+ break;
+ }
+ }
+
+ if (UNLIKELY(v1 == v3)) {
+ // printf("This should never happen, but does sometimes!\n");
+ break;
+ }
+
+ switch (method) {
+ case 0:
+ return bm_edge_calc_rotate_beauty__area(v1, v2, v3, v4);
+ default:
+ return bm_edge_calc_rotate_beauty__angle(v1, v2, v3, v4);
+ }
+ } while (false);
+
+ return FLT_MAX;
+}
+
/* -------------------------------------------------------------------- */
/* Update the edge cost of rotation in the heap */
/* 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,
- const int flag)
+ const short flag, const short method)
{
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
const int i = BM_elem_index_get(e);
@@ -277,7 +324,7 @@
{
/* recalculate edge */
- const float cost = bm_edge_calc_rotate_beauty(e, flag);
+ const float cost = bm_edge_calc_rotate_beauty(e, flag, method);
if (cost < 0.0f) {
eheap_table[i] = BLI_heap_insert(eheap, cost, e);
}
@@ -290,18 +337,18 @@
/* we have rotated an edge, tag other edges and clear this one */
static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GSet **edge_state_arr,
- const int flag)
+ const short flag, const short method)
{
BMLoop *l;
BLI_assert(e->l->f->len == 3 &&
e->l->radial_next->f->len == 3);
l = e->l;
- bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag);
- bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag);
+ bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag, method);
+ bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag, method);
l = l->radial_next;
- bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag);
- bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag);
+ bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr, flag, method);
+ bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr, flag, method);
}
/* -------------------------------------------------------------------- */
@@ -315,12 +362,12 @@
* have their index values set according to their position in the array.
*/
static void bm_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len,
- const int flag)
+ const short flag, const short method)
{
Heap *eheap; /* edge heap */
HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */
- GSet **edge_state_arr = MEM_callocN(edge_array_len * sizeof(GSet *), __func__);
+ GSet **edge_state_arr = MEM_callocN((size_t)edge_array_len * sizeof(GSet *), __func__);
BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 512, 512, BLI_MEMPOOL_SYSMALLOC);
int i;
@@ -328,13 +375,13 @@
TIMEIT_START(beautify_fill);
#endif
- eheap = BLI_heap_new_ex(edge_array_len);
- eheap_table = MEM_mallocN(sizeof(HeapNode *) * edge_array_len, __func__);
+ eheap = BLI_heap_new_ex((unsigned int)edge_array_len);
+ eheap_table = MEM_mallocN(sizeof(HeapNode *) * (size_t)edge_array_len, __func__);
/* build heap */
for (i = 0; i < edge_array_len; i++) {
BMEdge *e = edge_array[i];
- const float cost = bm_edge_calc_rotate_beauty(e, flag);
+ const float cost = bm_edge_calc_rotate_beauty(e, flag, method);
if (cost < 0.0f) {
eheap_table[i] = BLI_heap_insert(eheap, cost, e);
}
@@ -371,7 +418,7 @@
BM_elem_index_set(e, i);
/* recalculate faces connected on the heap */
- bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr, flag);
+ bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr, flag, method);
/* update flags */
BMO_elem_flag_enable(bm, e, ELE_NEW);
@@ -405,11 +452,11 @@
BMFace *f;
BMEdge *e;
const bool use_restrict_tag = BMO_slot_bool_get(op->slots_in, "use_restrict_tag");
- const int flag = (use_restrict_tag ? VERT_RESTRICT_TAG : 0);
+ const short flag = (use_restrict_tag ? VERT_RESTRICT_TAG : 0);
+ const short method = (short)BMO_slot_int_get(op->slots_in, "method");
BMEdge **edge_array;
int edge_array_len = 0;
-
BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
if (f->len == 3) {
BMO_elem_flag_enable(bm, f, FACE_MARK);
@@ -421,7 +468,7 @@
}
/* will over alloc if some edges can't be rotated */
- edge_array = MEM_mallocN(sizeof(*edge_array) * BMO_slot_buffer_count(op->slots_in, "edges"), __func__);
+ edge_array = MEM_mallocN(sizeof(*edge_array) * (size_t)BMO_slot_buffer_count(op->slots_in, "edges"), __func__);
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
@@ -439,7 +486,7 @@
}
bm->elem_index_dirty |= BM_EDGE;
- bm_mesh_beautify_fill(bm, edge_array, edge_array_len, flag);
+ bm_mesh_beautify_fill(bm, edge_array, edge_array_len, flag, method);
MEM_freeN(edge_array);
Modified: trunk/blender/source/blender/bmesh/operators/bmo_bridge.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_bridge.c 2013-09-17 22:48:08 UTC (rev 60209)
+++ trunk/blender/source/blender/bmesh/operators/bmo_bridge.c 2013-09-17 23:23:32 UTC (rev 60210)
@@ -421,8 +421,8 @@
BMO_op_initf(bm, &op_sub, 0,
- "beautify_fill faces=%hf edges=ae use_restrict_tag=%b",
- BM_ELEM_TAG, true);
+ "beautify_fill faces=%hf edges=ae use_restrict_tag=%b method=%i",
+ BM_ELEM_TAG, true, 1);
if (use_edgeout) {
BMOIter siter;
More information about the Bf-blender-cvs
mailing list