Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_structure.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c115
1 files changed, 102 insertions, 13 deletions
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index 3e8002c0192..cb302139a4c 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -40,19 +40,56 @@
* MISC utility functions.
*/
-bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new)
+void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src)
{
- if (e->v1 == v_orig) {
- e->v1 = v_new;
+ if (e->v1 == v_src) {
+ e->v1 = v_dst;
e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
- return true;
}
- else if (e->v2 == v_orig) {
- e->v2 = v_new;
+ else if (e->v2 == v_src) {
+ e->v2 = v_dst;
e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
- return true;
}
- return false;
+ else {
+ BLI_assert(0);
+ }
+}
+
+/**
+ * Handles all connected data, use with care.
+ *
+ * Assumes caller has setup correct state before the swap is done.
+ */
+void bmesh_edge_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src)
+{
+ /* swap out loops */
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->v == v_src) {
+ l_iter->v = v_dst;
+ }
+ else if (l_iter->next->v == v_src) {
+ l_iter->next->v = v_dst;
+ }
+ else {
+ BLI_assert(l_iter->prev->v != v_src);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+
+ /* swap out edges */
+ bmesh_disk_vert_replace(e, v_dst, v_src);
+}
+
+void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src)
+{
+ BLI_assert(e->v1 == v_src || e->v2 == v_src);
+ bmesh_disk_edge_remove(e, v_src); /* remove e from tv's disk cycle */
+ bmesh_disk_vert_swap(e, v_dst, v_src); /* swap out tv for v_new in e */
+ bmesh_disk_edge_append(e, v_dst); /* add e to v_dst's disk cycle */
+ BLI_assert(e->v1 != e->v2);
}
/**
@@ -88,6 +125,7 @@ bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new)
* the disk cycle has no problems dealing with non-manifold conditions involving faces.
*
* Functions relating to this cycle:
+ * - #bmesh_disk_vert_replace
* - #bmesh_disk_edge_append
* - #bmesh_disk_edge_remove
* - #bmesh_disk_edge_next
@@ -206,13 +244,29 @@ int bmesh_disk_count(const BMVert *v)
return count;
}
+int bmesh_disk_count_ex(const BMVert *v, const int count_max)
+{
+ int count = 0;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+ e_iter = e_first = v->e;
+ do {
+ count++;
+ if (count == count_max) {
+ break;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return count;
+}
+
bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
{
BMEdge *e_iter;
if (!BM_vert_in_edge(e, v))
return false;
- if (bmesh_disk_count(v) != len || len == 0)
+ if (bmesh_disk_count_ex(v, len + 1) != len || len == 0)
return false;
e_iter = e;
@@ -236,9 +290,9 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
int bmesh_disk_facevert_count(const BMVert *v)
{
/* is there an edge on this vert at all */
+ int count = 0;
if (v->e) {
BMEdge *e_first, *e_iter;
- int count = 0;
/* first, loop around edge */
e_first = e_iter = v->e;
@@ -247,11 +301,29 @@ int bmesh_disk_facevert_count(const BMVert *v)
count += bmesh_radial_facevert_count(e_iter->l, v);
}
} while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- return count;
}
- else {
- return 0;
+ return count;
+}
+
+int bmesh_disk_facevert_count_ex(const BMVert *v, const int count_max)
+{
+ /* is there an edge on this vert at all */
+ int count = 0;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+
+ /* first, loop around edge */
+ e_first = e_iter = v->e;
+ do {
+ if (e_iter->l) {
+ count += bmesh_radial_facevert_count_ex(e_iter->l, v, count_max - count);
+ if (count == count_max) {
+ break;
+ }
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
}
+ return count;
}
/**
@@ -456,6 +528,23 @@ int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v)
return count;
}
+int bmesh_radial_facevert_count_ex(const BMLoop *l, const BMVert *v, const int count_max)
+{
+ const BMLoop *l_iter;
+ int count = 0;
+ l_iter = l;
+ do {
+ if (l_iter->v == v) {
+ count++;
+ if (count == count_max) {
+ break;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return count;
+}
+
/**
* \brief RADIAL CHECK FACE VERT
*