diff options
author | Howard Trickey <howard.trickey@gmail.com> | 2012-03-06 16:09:35 +0400 |
---|---|---|
committer | Howard Trickey <howard.trickey@gmail.com> | 2012-03-06 16:09:35 +0400 |
commit | d87f08cbaabe7d07f873adebd617747b3ae31bc4 (patch) | |
tree | 7b5219f0fc3f2e6cf767a8d834a7f0c72aa33bb7 | |
parent | 92322b57d4652275e328b8ee94d631e72a82ed0e (diff) |
Add BM_face_split_n which splits a face with intermediate points with given coordinates.
This will be used in soon-to-be-commited knife tool rewrite.
Interpolates using the original face.
Also fixed or improved a couple of comments.
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 13 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.c | 76 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mods.h | 5 |
3 files changed, 87 insertions, 7 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index c95983c4327..a21834b1f1c 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -1216,11 +1216,16 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, * \brief Split Edge Make Vert (SEMV) * * Takes \a e edge and splits it into two, creating a new vert. + * \a tv should be one end of \a e : the newly created edge + * will be attached to that end and is returned in \a r_e. * * \par Examples: * - * Before: OV---------TV - * After: OV----NV---TV + * E + * Before: OV-------------TV + * + * E RE + * After: OV------NV-----TV * * \return The newly created BMVert pointer. */ @@ -1235,10 +1240,8 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) ov = bmesh_edge_other_vert_get(e, tv); - /* count valence of v1 */ valence1 = bmesh_disk_count(ov); - /* count valence of v2 */ valence2 = bmesh_disk_count(tv); nv = BM_vert_create(bm, tv->co, tv); @@ -1247,7 +1250,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) bmesh_disk_edge_remove(ne, tv); bmesh_disk_edge_remove(ne, nv); - /* remove e from v2's disk cycle */ + /* remove e from tv's disk cycle */ bmesh_disk_edge_remove(e, tv); /* swap out tv for nv in e */ diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 1347e657a99..102dec7a4b4 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -314,7 +314,7 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f) * \param f the original face * \param v1, v2 vertices which define the split edge, must be different * \param r_l pointer which will receive the BMLoop for the split edge in the new face - * \param example Face used to initialize settings + * \param example Edge used for attributes of splitting edge, if non-NULL * * \return Pointer to the newly created face representing one side of the split * if the split is successful (and the original original face will be the @@ -371,6 +371,75 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l } /** + * \brief Face Split with intermediate points + * + * Like BM_face_split, but with an edge split by \a n intermediate points with given coordinates. + * + * \param bm The bmesh + * \param f the original face + * \param v1, v2 vertices which define the split edge, must be different + * \param co Array of coordinates for intermediate points + * \param n Length of \a cos (must be > 0) + * \param r_l pointer which will receive the BMLoop for the first split edge (from \a v1) in the new face + * \param example Edge used for attributes of splitting edge, if non-NULL + * + * \return Pointer to the newly created face representing one side of the split + * if the split is successful (and the original original face will be the + * other side). NULL if the split fails. + */ +BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[][3], int n, + BMLoop **r_l, BMEdge *example) +{ + BMFace *nf, *of; + BMLoop *l_dummy; + BMEdge *e, *newe; + BMVert *newv; + int i, j; + + BLI_assert(v1 != v2); + + of = BM_face_copy(bm, f, TRUE, TRUE); + + if (!r_l) + r_l = &l_dummy; + +#ifdef USE_BMESH_HOLES + nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example); +#else + nf = bmesh_sfme(bm, f, v1, v2, r_l, example); +#endif + /* bmesh_sfme returns in r_l a Loop for nf going from v1 to v2. + * The radial_next is for f and goes from v2 to v1 */ + + if (nf) { + e = (*r_l)->e; + for (i = 0; i < n; i++) { + newv = bmesh_semv(bm, v2, e, &newe); + BLI_assert(newv != NULL); + /* bmesh_semv returns in newe the edge going from newv to tv */ + copy_v3_v3(newv->co, cos[i]); + + /* interpolate the loop data for the loops with v==newv, using orig face */ + for (j = 0; j < 2; j++) { + BMEdge *e_iter = (j==0)? e : newe; + BMLoop *l_iter = e_iter->l; + do { + if (l_iter->v == newv) { + /* this interpolates both loop and vertex data */ + BM_loop_interp_from_face(bm, l_iter, of, TRUE, TRUE); + } + } while ((l_iter = l_iter->radial_next) != e_iter->l); + } + e = newe; + } + } + + BM_face_verts_kill(bm, of); + + return nf; +} + +/** * \brief Vert Collapse Faces * * Collapses vertex \a kv that has only two manifold edges @@ -534,7 +603,10 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, * \brief Edge Split * * Splits an edge. \a v should be one of the vertices in \a e and defines - * the direction of the splitting operation for interpolation purposes. + * the "from" end of the splitting operation: the new vertex will be + * \a percent of the way from \a v to the other end. + * The newly created edge is attached to \a v and is returned in \a r_e. + * The original edge \a e will be the other half of the split. * * \return The new vert */ diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h index 32faa0333bf..70b79d6b6e3 100644 --- a/source/blender/bmesh/intern/bmesh_mods.h +++ b/source/blender/bmesh/intern/bmesh_mods.h @@ -42,6 +42,11 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l, BMEdge *example); +BMFace *BM_face_split_n(BMesh *bm, BMFace *f, + BMVert *v1, BMVert *v2, + float cos[][3], int n, + BMLoop **r_l, BMEdge *example); + BMEdge* BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, const short join_faces, const short kill_degenerate_faces); BMEdge* BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, |