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')
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c419
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect_edges.c313
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect_edges.h6
3 files changed, 319 insertions, 419 deletions
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 07e159b3241..bc84c6872c4 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -60,16 +60,7 @@
#define BEVEL_MATCH_SPEC_WEIGHT 0.2
//#define DEBUG_CUSTOM_PROFILE_CUTOFF
-//#define DEBUG_CUSTOM_PROFILE_SAMPLE
-
-#if defined(DEBUG_PROFILE_ORIENTATION_DRAW) || defined(DEBUG_CUSTOM_PROFILE_PIPE)
-static float debug_color_red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
-static float debug_color_blue[4] = {0.0f, 0.0f, 1.0f, 1.0f};
-extern void DRW_debug_sphere(const float center[3], const float radius, const float color[4]);
-extern void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]);
-#endif
-
-/* happens far too often, uncomment for development */
+/* Happens far too often, uncomment for development. */
// #define BEVEL_ASSERT_PROJECT
/* for testing */
@@ -155,6 +146,8 @@ typedef struct Profile {
float *prof_co;
/** Like prof_co, but for seg power of 2 >= seg */
float *prof_co_2;
+ /** Mark a special case so the these parameters aren't reset with others. */
+ bool special_params;
} Profile;
#define PRO_SQUARE_R 1e4f
#define PRO_CIRCLE_R 2.0f
@@ -266,7 +259,7 @@ typedef struct BevVert {
VMesh *vmesh;
} BevVert;
-/* face classification: note depend on F_RECON > F_EDGE > F_VERT */
+/* Face classification. Note: depends on F_RECON > F_EDGE > F_VERT */
typedef enum {
/** Used when there is no face at all */
F_NONE,
@@ -290,10 +283,6 @@ enum {
ANGLE_LARGER = 1,
};
-#if 0
-static const char* fkind_names[] = {"F_NONE", "F_ORIG", "F_VERT", "F_EDGE", "F_RECON"}; /* DEBUG */
-#endif
-
/** Bevel parameters and state */
typedef struct BevelParams {
/** Records BevVerts made: key BMVert*, value BevVert* */
@@ -359,12 +348,8 @@ typedef struct BevelParams {
// #pragma GCC diagnostic ignored "-Wpadded"
-/* Some flags to re-enable old behavior for a while,
- * in case fixes broke things not caught by regression tests. */
-static int bev_debug_flags = 0;
-#define DEBUG_OLD_PLANE_SPECIAL (bev_debug_flags & 1)
-#define DEBUG_OLD_PROJ_TO_PERP_PLANE (bev_debug_flags & 2)
-#define DEBUG_OLD_FLAT_MID (bev_debug_flags & 4)
+/* Only for debugging, shouldn't be in blender repo. */
+// #include "bevdebug.c"
/* use the unused _BM_ELEM_TAG_ALT flag to flag the 'long' loops (parallel to beveled edge)
* of edge-polygons. */
@@ -1314,7 +1299,10 @@ static void offset_in_plane(EdgeHalf *e, const float plane_no[3], bool left, flo
}
/* Calculate the point on e where line (co_a, co_b) comes closest to and return it in projco. */
-static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3], float projco[3])
+static void project_to_edge(const BMEdge *e,
+ const float co_a[3],
+ const float co_b[3],
+ float projco[3])
{
float otherco[3];
@@ -1330,16 +1318,13 @@ static void project_to_edge(BMEdge *e, const float co_a[3], const float co_b[3],
* It is the closest point on the beveled edge to the line segment between bndv and bndv->next. */
static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
{
- EdgeHalf *e;
- Profile *pro;
float start[3], end[3], co3[3], d1[3], d2[3];
- bool do_linear_interp;
+ bool do_linear_interp = true;
+ EdgeHalf *e = bndv->ebev;
+ Profile *pro = &bndv->profile;
copy_v3_v3(start, bndv->nv.co);
copy_v3_v3(end, bndv->next->nv.co);
- pro = &bndv->profile;
- e = bndv->ebev;
- do_linear_interp = true;
if (e) {
do_linear_interp = false;
pro->super_r = bp->pro_super_r;
@@ -1350,23 +1335,8 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
}
normalize_v3(pro->proj_dir);
project_to_edge(e->e, start, end, pro->middle);
- if (DEBUG_OLD_PROJ_TO_PERP_PLANE) {
- /* Put arc endpoints on plane with normal proj_dir, containing middle. */
- add_v3_v3v3(co3, start, pro->proj_dir);
- if (!isect_line_plane_v3(pro->start, start, co3, pro->middle, pro->proj_dir)) {
- /* Shouldn't happen. */
- copy_v3_v3(pro->start, start);
- }
- add_v3_v3v3(co3, end, pro->proj_dir);
- if (!isect_line_plane_v3(pro->end, end, co3, pro->middle, pro->proj_dir)) {
- /* Shouldn't happen. */
- copy_v3_v3(pro->end, end);
- }
- }
- else {
- copy_v3_v3(pro->start, start);
- copy_v3_v3(pro->end, end);
- }
+ copy_v3_v3(pro->start, start);
+ copy_v3_v3(pro->end, end);
/* Default plane to project onto is the one with triangle start - middle - end in it. */
sub_v3_v3v3(d1, pro->middle, start);
sub_v3_v3v3(d2, pro->middle, end);
@@ -1384,69 +1354,55 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
* If the profile is going to lead into unbeveled edges on each side
* (that is, both BoundVerts are "on-edge" points on non-beveled edges)
*/
- if (DEBUG_OLD_PLANE_SPECIAL && (e->prev->is_bev || e->next->is_bev)) {
- do_linear_interp = true;
- }
- else {
- if (DEBUG_OLD_PROJ_TO_PERP_PLANE) {
- copy_v3_v3(pro->start, start);
- copy_v3_v3(pro->end, end);
- }
- if (DEBUG_OLD_FLAT_MID) {
- copy_v3_v3(pro->middle, bv->v->co);
- }
- else {
- copy_v3_v3(pro->middle, bv->v->co);
- if (e->prev->is_bev && e->next->is_bev && bv->selcount >= 3) {
- /* Want mid at the meet point of next and prev offset edges. */
- float d3[3], d4[3], co4[3], meetco[3], isect2[3];
- int isect_kind;
-
- sub_v3_v3v3(d3, e->prev->e->v1->co, e->prev->e->v2->co);
- sub_v3_v3v3(d4, e->next->e->v1->co, e->next->e->v2->co);
- normalize_v3(d3);
- normalize_v3(d4);
- if (nearly_parallel(d3, d4)) {
- /* Offset lines are collinear - want linear interpolation. */
- mid_v3_v3v3(pro->middle, start, end);
- do_linear_interp = true;
- }
- else {
- add_v3_v3v3(co3, start, d3);
- add_v3_v3v3(co4, end, d4);
- isect_kind = isect_line_line_v3(start, co3, end, co4, meetco, isect2);
- if (isect_kind != 0) {
- copy_v3_v3(pro->middle, meetco);
- }
- else {
- /* Offset lines don't intersect - want linear interpolation. */
- mid_v3_v3v3(pro->middle, start, end);
- do_linear_interp = true;
- }
- }
- }
- }
- copy_v3_v3(pro->end, end);
- sub_v3_v3v3(d1, pro->middle, start);
- normalize_v3(d1);
- sub_v3_v3v3(d2, pro->middle, end);
- normalize_v3(d2);
- cross_v3_v3v3(pro->plane_no, d1, d2);
- normalize_v3(pro->plane_no);
- if (nearly_parallel(d1, d2)) {
- /* Whole profile is collinear with edge: just interpolate. */
+ copy_v3_v3(pro->middle, bv->v->co);
+ if (e->prev->is_bev && e->next->is_bev && bv->selcount >= 3) {
+ /* Want mid at the meet point of next and prev offset edges. */
+ float d3[3], d4[3], co4[3], meetco[3], isect2[3];
+ int isect_kind;
+
+ sub_v3_v3v3(d3, e->prev->e->v1->co, e->prev->e->v2->co);
+ sub_v3_v3v3(d4, e->next->e->v1->co, e->next->e->v2->co);
+ normalize_v3(d3);
+ normalize_v3(d4);
+ if (nearly_parallel(d3, d4)) {
+ /* Offset lines are collinear - want linear interpolation. */
+ mid_v3_v3v3(pro->middle, start, end);
do_linear_interp = true;
}
else {
- copy_v3_v3(pro->plane_co, bv->v->co);
- copy_v3_v3(pro->proj_dir, pro->plane_no);
+ add_v3_v3v3(co3, start, d3);
+ add_v3_v3v3(co4, end, d4);
+ isect_kind = isect_line_line_v3(start, co3, end, co4, meetco, isect2);
+ if (isect_kind != 0) {
+ copy_v3_v3(pro->middle, meetco);
+ }
+ else {
+ /* Offset lines don't intersect - want linear interpolation. */
+ mid_v3_v3v3(pro->middle, start, end);
+ do_linear_interp = true;
+ }
}
}
+ copy_v3_v3(pro->end, end);
+ sub_v3_v3v3(d1, pro->middle, start);
+ normalize_v3(d1);
+ sub_v3_v3v3(d2, pro->middle, end);
+ normalize_v3(d2);
+ cross_v3_v3v3(pro->plane_no, d1, d2);
+ normalize_v3(pro->plane_no);
+ if (nearly_parallel(d1, d2)) {
+ /* Whole profile is collinear with edge: just interpolate. */
+ do_linear_interp = true;
+ }
+ else {
+ copy_v3_v3(pro->plane_co, bv->v->co);
+ copy_v3_v3(pro->proj_dir, pro->plane_no);
+ }
}
copy_v3_v3(pro->plane_co, start);
}
else if (bndv->is_arc_start) {
- /* Assume pro->middle was alredy set. */
+ /* Assume pro->middle was already set. */
copy_v3_v3(pro->start, start);
copy_v3_v3(pro->end, end);
pro->super_r = PRO_CIRCLE_R;
@@ -1455,6 +1411,17 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
zero_v3(pro->proj_dir);
do_linear_interp = false;
}
+ else if (bp->vertex_only) {
+ copy_v3_v3(pro->start, start);
+ copy_v3_v3(pro->middle, bv->v->co);
+ copy_v3_v3(pro->end, end);
+ pro->super_r = bp->pro_super_r;
+ zero_v3(pro->plane_co);
+ zero_v3(pro->plane_no);
+ zero_v3(pro->proj_dir);
+ do_linear_interp = false;
+ }
+
if (do_linear_interp) {
pro->super_r = PRO_LINE_R;
copy_v3_v3(pro->start, start);
@@ -1467,11 +1434,11 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
}
}
-/* Maybe move the profile plane for bndv->ebev to the plane its profile's start, and the
+/* Maybe move the profile plane for bndv->ebev to the plane its profile's start, and the
* original beveled vert, bmv. This will usually be the plane containing its adjacent
* non-beveled edges, but sometimes the start and the end are not on those edges.
*
- * Currently just used in build boundary terminal edge */
+ * Currently just used in #build_boundary_terminal_edge */
static void move_profile_plane(BoundVert *bndv, BMVert *bmvert)
{
float d1[3], d2[3], no[3], no2[3], no3[3], dot2, dot3;
@@ -1496,6 +1463,9 @@ static void move_profile_plane(BoundVert *bndv, BMVert *bmvert)
copy_v3_v3(bndv->profile.plane_no, no);
}
}
+
+ /* We've changed the parameters from their defaults, so don't recalculate them later. */
+ pro->special_params = true;
}
/* Move the profile plane for the two BoundVerts involved in a weld.
@@ -1531,6 +1501,10 @@ static void move_weld_profile_planes(BevVert *bv, BoundVert *bndv1, BoundVert *b
copy_v3_v3(bndv2->profile.plane_no, no);
}
}
+
+ /* We've changed the parameters from their defaults, so don't recalculate them later. */
+ bndv1->profile.special_params = true;
+ bndv2->profile.special_params = true;
}
/* return 1 if a and b are in CCW order on the normal side of f,
@@ -1748,6 +1722,7 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, b
else {
map_ok = make_unit_square_map(pro->start, pro->middle, pro->end, map);
}
+
if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && map_ok) {
/* Calculate the "height" of the profile by putting the (0,0) and (1,1) corners of the
* un-transformed profile throughout the 2D->3D map and calculating the distance between them.
@@ -1759,6 +1734,7 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, b
mul_v3_m4v3(top_corner, map, p);
pro->height = len_v3v3(bottom_corner, top_corner);
}
+
/* The first iteration is the nseg case, the second is the seg_2 case (if it's needed) */
for (i = 0; i < 2; i++) {
if (i == 0) {
@@ -2321,15 +2297,20 @@ static bool eh_on_plane(EdgeHalf *e)
/* Calculate the profiles for all the BoundVerts of VMesh vm */
static void calculate_vm_profiles(BevelParams *bp, BevVert *bv, VMesh *vm)
{
- BoundVert *bndv;
-
- bndv = vm->boundstart;
+ BoundVert *bndv = vm->boundstart;
do {
- set_profile_params(bp, bv, bndv);
- /* Use the miter profile spacing struct if the default is filled with the custom profile. */
- bool miter_profile = bp->use_custom_profile && (bndv->is_arc_start || bndv->is_patch_start);
- /* Don't bother reversing the profile if it's a miter profile */
- bool reverse_profile = !bndv->is_profile_start && !miter_profile;
+ /* In special cases the params will have already been set. */
+ if (!bndv->profile.special_params) {
+ set_profile_params(bp, bv, bndv);
+ }
+ bool miter_profile = false;
+ bool reverse_profile = false;
+ if (bp->use_custom_profile) {
+ /* Use the miter profile spacing struct if the default is filled with the custom profile. */
+ miter_profile = (bndv->is_arc_start || bndv->is_patch_start);
+ /* Don't bother reversing the profile if it's a miter profile */
+ reverse_profile = !bndv->is_profile_start && !miter_profile;
+ }
calculate_profile(bp, bndv, reverse_profile, miter_profile);
} while ((bndv = bndv->next) != vm->boundstart);
}
@@ -2357,8 +2338,6 @@ static void build_boundary_vertex_only(BevelParams *bp, BevVert *bv, bool constr
}
} while ((e = e->next) != efirst);
- calculate_vm_profiles(bp, bv, vm);
-
if (construct) {
set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp);
if (vm->count == 2) {
@@ -2471,15 +2450,13 @@ static void build_boundary_terminal_edge(BevelParams *bp,
}
}
}
- calculate_vm_profiles(bp, bv, vm);
if (bv->edgecount >= 3) {
/* Special case: snap profile to plane of adjacent two edges. */
bndv = vm->boundstart;
BLI_assert(bndv->ebev != NULL);
+ set_profile_params(bp, bv, bndv);
move_profile_plane(bndv, bv->v);
- /* This step happens before the profile orientation pass so don't reverse the profile. */
- calculate_profile(bp, bndv, false, false);
}
if (construct) {
@@ -2506,17 +2483,6 @@ static void build_boundary_terminal_edge(BevelParams *bp,
vm->mesh_kind = M_POLY;
}
}
-#ifdef DEBUG_CUSTOM_PROFILE_WELD
- if (bp->seg > 1) {
- printf("Terminal Edge Profile Coordinates:\n");
- for (int k = 0; k < bp->seg; k++) {
- printf("%0.4f, %0.4f, %0.4f\n",
- (double)vm->boundstart->profile.prof_co[3 * k],
- (double)vm->boundstart->profile.prof_co[3 * k + 1],
- (double)vm->boundstart->profile.prof_co[3 * k + 2]);
- }
- }
-#endif
}
/* Helper for build_boundary to handle special miters */
@@ -2831,8 +2797,6 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct)
adjust_miter_coords(bp, bv, emiter);
}
- calculate_vm_profiles(bp, bv, vm);
-
if (construct) {
set_bound_vert_seams(bv, bp->mark_seam, bp->mark_sharp);
@@ -3185,53 +3149,6 @@ static void regularize_profile_orientation(BevelParams *bp, BMEdge *bme)
}
}
-#ifdef DEBUG_PROFILE_ORIENTATION_DRAW
-/**
- * Draws markers on beveled edges showing the side that the profile starts on. A sphere shows
- * the start side of the profile where it starts, and the lines connected to the sphere show which
- * edge the orientation corresponds to.
- * \note Only drawn while bevel is calculating, the debug geometry is not persistent.
- */
-static void debug_draw_profile_orientation(BevelParams *bp, BMesh *bm)
-{
- BMIter iter;
- BMEdge *bmedge;
- float middle[3];
-
- BM_ITER_MESH (bmedge, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(bmedge, BM_ELEM_TAG)) {
- mid_v3_v3v3(middle, bmedge->v1->co, bmedge->v2->co);
-
- /* Draw the orientation for the first side of the edge. */
- EdgeHalf *edge_half = find_edge_half(find_bevvert(bp, bmedge->v1), bmedge);
- if (edge_half->leftv->is_profile_start) { /* The left boundvert defines the profiles. */
- DRW_debug_sphere(edge_half->leftv->nv.co, 0.04f, debug_color_red);
- DRW_debug_line_v3v3(middle, edge_half->leftv->nv.co, debug_color_red);
- DRW_debug_line_v3v3(bmedge->v1->co, edge_half->leftv->nv.co, debug_color_red);
- }
- else {
- DRW_debug_sphere(edge_half->rightv->nv.co, 0.04f, debug_color_red);
- DRW_debug_line_v3v3(middle, edge_half->rightv->nv.co, debug_color_red);
- DRW_debug_line_v3v3(bmedge->v1->co, edge_half->rightv->nv.co, debug_color_red);
- }
-
- /* Draw the orientation for the second side of the edge. */
- edge_half = find_edge_half(find_bevvert(bp, bmedge->v2), bmedge);
- if (edge_half->leftv->is_profile_start) {
- DRW_debug_sphere(edge_half->leftv->nv.co, 0.05f, debug_color_blue);
- DRW_debug_line_v3v3(middle, edge_half->leftv->nv.co, debug_color_blue);
- DRW_debug_line_v3v3(bmedge->v2->co, edge_half->leftv->nv.co, debug_color_blue);
- }
- else {
- DRW_debug_sphere(edge_half->rightv->nv.co, 0.05f, debug_color_blue);
- DRW_debug_line_v3v3(middle, edge_half->rightv->nv.co, debug_color_blue);
- DRW_debug_line_v3v3(bmedge->v2->co, edge_half->rightv->nv.co, debug_color_blue);
- }
- }
- }
-}
-#endif
-
/* Adjust the offsets for a single cycle or chain.
* For chains and some cycles, a fast solution exists.
* Otherwise, we set up and solve a linear least squares problem
@@ -3643,9 +3560,6 @@ static void vmesh_copy_equiv_verts(VMesh *vm)
/* Calculate and return in r_cent the centroid of the center poly */
static void vmesh_center(VMesh *vm, float r_cent[3])
{
-#ifdef DEBUG_CUSTOM_PROFILE_ADJ
- printf("VMESH CENTER\n");
-#endif
int n, ns2, i;
n = vm->count;
@@ -4157,9 +4071,8 @@ static VMesh *make_cube_corner_adj_vmesh(BevelParams *bp)
copy_v3_v3(bndv->profile.plane_co, bndv->profile.start);
cross_v3_v3v3(bndv->profile.plane_no, bndv->profile.start, bndv->profile.end);
copy_v3_v3(bndv->profile.proj_dir, bndv->profile.plane_no);
- /* No need to reverse the profile or use the miter profile spacing struct because this case
- * isn't used with custom profiles. */
- calculate_profile(bp, bndv, false, false);
+ /* Calculate profiles again because we started over with new boundverts. */
+ calculate_profile(bp, bndv, false, false); /* No custom profiles in this case. */
/* Just building the boundaries here, so sample the profile halfway through */
get_profile_point(bp, &bndv->profile, 1, 2, mesh_vert(vm0, i, 0, 1)->co);
@@ -4394,14 +4307,6 @@ static void snap_to_pipe_profile(BoundVert *vpipe, bool midline, float co[3])
*/
static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
{
-#ifdef DEBUG_CUSTOM_PROFILE_PIPE
- printf("PIPE ADJ VMESH\n");
- float green[4] = {0.0f, 1.0f, 0.0f, 1.0f};
- float blue[4] = {0.0f, 0.0f, 1.0f, 1.0f};
- float red[4] = {1.0f, 0.0f, 0.0f, 1.0f};
- float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- float *color;
-#endif
int i, j, k, n_bndv, ns, half_ns, ipipe1, ipipe2, ring;
VMesh *vm;
bool even, midline;
@@ -4418,11 +4323,6 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
ipipe1 = vpipe->index;
ipipe2 = vpipe->next->next->index;
-#ifdef DEBUG_CUSTOM_PROFILE_PIPE
- printf("ipipe1: %d\n", ipipe1);
- printf("ipipe2: %d\n", ipipe2);
-#endif
-
for (i = 0; i < n_bndv; i++) {
for (j = 1; j <= half_ns; j++) {
for (k = 0; k <= half_ns; k++) {
@@ -4456,18 +4356,6 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
/* Place the vertex by interpolatin between the two profile points using the factor. */
interp_v3_v3v3(mesh_vert(vm, i, j, k)->co, profile_point_pipe1, profile_point_pipe2, f);
-#ifdef DEBUG_CUSTOM_PROFILE_PIPE
- printf("(%d, %d, %d)\n", i, j, k);
- printf("f: %.3f\n", f);
- printf("point 1: (%.3f, %.3f, %.3f)\n",
- profile_point_pipe1[0],
- profile_point_pipe1[1],
- profile_point_pipe1[2]);
- printf("point 2: (%.3f, %.3f, %.3f)\n",
- profile_point_pipe2[0],
- profile_point_pipe2[1],
- profile_point_pipe2[2]);
-#endif
}
else {
/* A tricky case is for the 'square' profiles and an even nseg: we want certain
@@ -4479,33 +4367,6 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe)
}
}
}
-#ifdef DEBUG_CUSTOM_PROFILE_PIPE
- /* Draw the locations of all the vertices after the "snapping" process */
- for (i = 0; i < n_bndv; i++) {
- for (j = 1; j <= half_ns; j++) {
- for (k = 1; k <= ns; k++) {
- if (!is_canon(vm, i, j, k)) {
- continue;
- }
- switch (i) {
- case 0:
- color = red;
- break;
- case 1:
- color = green;
- break;
- case 2:
- color = blue;
- break;
- case 3:
- color = white;
- break;
- }
- DRW_debug_sphere(mesh_vert(vm, i, j, k)->co, 0.01f, color);
- }
- }
- }
-#endif
return vm;
}
@@ -4922,20 +4783,6 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert
odd = ns % 2;
BLI_assert(n_bndv >= 3 && ns > 1);
- /* Add support for profiles in vertex only in-plane bevels. */
- if (bp->vertex_only) {
- bndv = bv->vmesh->boundstart;
- do {
- Profile *pro = &bndv->profile;
- copy_v3_v3(pro->middle, bv->v->co);
- pro->super_r = bp->pro_super_r;
- bool miter_profile = bp->use_custom_profile && (bndv->is_arc_start || bndv->is_patch_start);
- /* Orientation doesn't matter when only beveling vertices */
- calculate_profile(bp, bndv, false, miter_profile);
- bndv = bndv->next;
- } while (bndv != bv->vmesh->boundstart);
- }
-
if (bp->pro_super_r == PRO_SQUARE_R && bv->selcount >= 3 && !odd && !bp->use_custom_profile) {
vm1 = square_out_adj_vmesh(bp, bv);
}
@@ -5105,6 +4952,7 @@ static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv)
{
#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
printf("BEVEL BUILD CUTOFF\n");
+# define F3(v) (v)[0], (v)[1], (v)[2]
int j;
#endif
int i;
@@ -5143,10 +4991,7 @@ static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv)
#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
printf("Corner vertices:\n");
for (j = 0; j < n_bndv; j++) {
- printf(" (%.3f, %.3f, %.3f)\n",
- (double)mesh_vert(bv->vmesh, j, 1, 0)->co[0],
- (double)mesh_vert(bv->vmesh, j, 1, 0)->co[1],
- (double)mesh_vert(bv->vmesh, j, 1, 0)->co[2]);
+ printf(" (%.3f, %.3f, %.3f)\n", F3(mesh_vert(bv->vmesh, j, 1, 0)->co));
}
#endif
@@ -5204,21 +5049,14 @@ static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv)
if (bndv->is_patch_start || bndv->is_arc_start) {
printf(" Miter profile\n");
}
- printf(" Corner 1: (%0.3f, %0.3f, %0.3f)\n",
- (double)mesh_vert(bv->vmesh, i, 1, 0)->co[0],
- (double)mesh_vert(bv->vmesh, i, 1, 0)->co[1],
- (double)mesh_vert(bv->vmesh, i, 1, 0)->co[2]);
+ printf(" Corner 1: (%0.3f, %0.3f, %0.3f)\n", F3(mesh_vert(bv->vmesh, i, 1, 0)->co));
#endif
/* Add profile point vertices to the face, including the last one. */
for (int k = 0; k < bp->seg + 1; k++) {
face_bmverts[k + 1] = mesh_vert(bv->vmesh, i, 0, k)->v; /* Leave room for first vert. */
#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
- printf(" Profile %d: (%0.3f, %0.3f, %0.3f)\n",
- k,
- (double)mesh_vert(bv->vmesh, i, 0, k)->co[0],
- (double)mesh_vert(bv->vmesh, i, 0, k)->co[1],
- (double)mesh_vert(bv->vmesh, i, 0, k)->co[2]);
+ printf(" Profile %d: (%0.3f, %0.3f, %0.3f)\n", k, F3(mesh_vert(bv->vmesh, i, 0, k)->co));
#endif
}
@@ -5226,10 +5064,7 @@ static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv)
if (build_center_face) {
face_bmverts[bp->seg + 2] = mesh_vert(bv->vmesh, i, 1, 1)->v;
#ifdef DEBUG_CUSTOM_PROFILE_CUTOFF
- printf(" Corner 2: (%0.3f, %0.3f, %0.3f)\n",
- (double)mesh_vert(bv->vmesh, i, 1, 1)->co[0],
- (double)mesh_vert(bv->vmesh, i, 1, 1)->co[1],
- (double)mesh_vert(bv->vmesh, i, 1, 1)->co[2]);
+ printf(" Corner 2: (%0.3f, %0.3f, %0.3f)\n", F3(mesh_vert(bv->vmesh, i, 1, 1)->co));
#endif
}
@@ -5428,7 +5263,6 @@ static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv)
* we have to make it here. */
static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
{
-
VMesh *vm = bv->vmesh;
BMVert *v1, *v2;
BMEdge *e_eg, *bme;
@@ -5455,8 +5289,6 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
zero_v3(pro->plane_co);
zero_v3(pro->plane_no);
zero_v3(pro->proj_dir);
- /* there's no orientation chain to continue so the orientation of the bevel doesn't matter. */
- calculate_profile(bp, bndv, false, false);
for (k = 1; k < ns; k++) {
get_profile_point(bp, pro, k, ns, co);
@@ -5519,15 +5351,17 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
}
else { /* Get the last of the two BoundVerts. */
weld2 = bndv;
+ set_profile_params(bp, bv, weld1);
+ set_profile_params(bp, bv, weld2);
move_weld_profile_planes(bv, weld1, weld2);
- if (!bp->use_custom_profile) { /* Else profile recalculated in next loop. */
- calculate_profile(bp, weld1, !weld1->is_profile_start, false);
- calculate_profile(bp, weld2, !weld2->is_profile_start, false);
- }
}
}
} while ((bndv = bndv->next) != vm->boundstart);
+ /* It's simpler to calculate all profiles only once at a single moment, so keep just a single
+ * profile calculation here, the last point before actual mesh verts are created. */
+ calculate_vm_profiles(bp, bv, vm);
+
/* Create new vertices and place them based on the profiles. */
/* Copy other ends to (i, 0, ns) for all i, and fill in profiles for edges. */
bndv = vm->boundstart;
@@ -5536,10 +5370,6 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
/* bndv's last vert along the boundary arc is the first of the next BoundVert's arc. */
copy_mesh_vert(vm, i, 0, ns, bndv->next->index, 0, 0);
- /* Fix the profile orientations if it's not a miter profile. */
- if (bp->use_custom_profile && !bndv->is_arc_start && !bndv->is_patch_start) {
- calculate_profile(bp, bndv, !bndv->is_profile_start, false);
- }
if (vm->mesh_kind != M_ADJ) {
for (k = 1; k < ns; k++) {
if (bndv->ebev) {
@@ -5589,24 +5419,6 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
copy_mesh_vert(bv->vmesh, weld2->index, 0, ns - k, weld1->index, 0, k);
}
}
-#ifdef DEBUG_CUSTOM_PROFILE_WELD
- if (weld && ns > 1) {
- printf("Weld1 profile coordinates:\n");
- for (k = 0; k < ns; k++) {
- printf("%0.4f, %0.4f, %0.4f\n",
- (double)weld1->profile.prof_co[3 * k],
- (double)weld1->profile.prof_co[3 * k + 1],
- (double)weld1->profile.prof_co[3 * k + 2]);
- }
- printf("Weld2 profile coordinates\n");
- for (k = 0; k < ns; k++) {
- printf("%0.4f, %0.4f, %0.4f\n",
- (double)weld2->profile.prof_co[3 * k],
- (double)weld2->profile.prof_co[3 * k + 1],
- (double)weld2->profile.prof_co[3 * k + 2]);
- }
- }
-#endif
/* Make sure the pipe case ADJ mesh is used for both the "Grid Fill" (ADJ) and cutoff options. */
vpipe = NULL;
@@ -7423,7 +7235,7 @@ void BM_mesh_bevel(BMesh *bm,
adjust_offsets(&bp, bm);
}
- /* Maintain consistent orientations for the unsymmetrical custom profiles. */
+ /* Maintain consistent orientations for the asymmetrical custom profiles. */
if (bp.use_custom_profile) {
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
@@ -7431,11 +7243,6 @@ void BM_mesh_bevel(BMesh *bm,
}
}
}
-#ifdef DEBUG_PROFILE_ORIENTATION_DRAW
- if (bp.use_custom_profile) {
- debug_draw_profile_orientation(&bp, bm);
- }
-#endif
/* Build the meshes around vertices, now that positions are final */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -7511,22 +7318,6 @@ void BM_mesh_bevel(BMesh *bm,
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
BM_elem_flag_disable(l, BM_ELEM_LONG_TAG);
}
-
-#ifdef DEBUG_CUSTOM_PROFILE_SAMPLE
- printf("Profile spacing:\n");
- printf("Seg values:\n");
- if (bp.pro_spacing.xvals != NULL) {
- for (int i = 0; i < bp.seg; i++) {
- printf("(%.3f, %.3f)\n", bp.pro_spacing.xvals[i], bp.pro_spacing.yvals[i]);
- }
- }
- if (bp.pro_spacing.seg_2 != bp.seg && bp.pro_spacing.seg_2 != 0) {
- printf("Seg_2 values:\n");
- for (int i = 0; i < bp.pro_spacing.seg_2; i++) {
- printf("(%0.2f, %0.2f)\n", bp.pro_spacing.xvals_2[i], bp.pro_spacing.yvals_2[i]);
- }
- }
-#endif
}
/* primary free */
diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c
index c3687c5d477..b25dc82aac9 100644
--- a/source/blender/bmesh/tools/bmesh_intersect_edges.c
+++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c
@@ -57,7 +57,7 @@ struct EDBMSplitBestFaceData {
* Track the range of vertices in edgenet along the faces normal,
* find the lowest since it's most likely to be most co-planar with the face.
*/
- float best_face_range_on_normal_axis;
+ float best_edgenet_range_on_face_normal;
BMFace *r_best_face;
};
@@ -76,11 +76,14 @@ static bool bm_vert_pair_share_best_splittable_face_cb(BMFace *f,
SWAP(float, min, max);
}
- BMVert *v_test = l_b->v;
BMEdge **e_iter = &data->edgenet[0];
+ BMEdge *e_next = data->edgenet[1];
+ BMVert *v_test = ELEM((*e_iter)->v1, e_next->v1, e_next->v2) ? (*e_iter)->v2 : (*e_iter)->v1;
+
int verts_len = data->edgenet_len - 1;
for (int i = verts_len; i--; e_iter++) {
v_test = BM_edge_other_vert(*e_iter, v_test);
+ BLI_assert(v_test != NULL);
if (!BM_face_point_inside_test(f, v_test->co)) {
return false;
}
@@ -93,9 +96,9 @@ static bool bm_vert_pair_share_best_splittable_face_cb(BMFace *f,
}
}
- const float test_face_range_on_normal_axis = max - min;
- if (test_face_range_on_normal_axis < data->best_face_range_on_normal_axis) {
- data->best_face_range_on_normal_axis = test_face_range_on_normal_axis;
+ const float test_edgenet_range_on_face_normal = max - min;
+ if (test_edgenet_range_on_face_normal < data->best_edgenet_range_on_face_normal) {
+ data->best_edgenet_range_on_face_normal = test_edgenet_range_on_face_normal;
data->r_best_face = f;
}
@@ -111,114 +114,79 @@ static bool bm_vert_pair_share_splittable_face_cb(BMFace *UNUSED(f),
float(*data)[3] = userdata;
float *v_a_co = data[0];
float *v_a_b_dir = data[1];
-
- float lambda;
- if (isect_ray_seg_v3(v_a_co, v_a_b_dir, l_a->prev->v->co, l_a->next->v->co, &lambda)) {
- if (IN_RANGE(lambda, 0.0f, 1.0f)) {
+ const float range_min = -FLT_EPSILON;
+ const float range_max = 1.0f + FLT_EPSILON;
+
+ float co[3];
+ float dir[3];
+ float lambda_a;
+ float lambda_b;
+
+ copy_v3_v3(co, l_a->prev->v->co);
+ sub_v3_v3v3(dir, l_a->next->v->co, co);
+ if (isect_ray_ray_v3(v_a_co, v_a_b_dir, co, dir, &lambda_a, &lambda_b)) {
+ if (IN_RANGE(lambda_a, range_min, range_max) && IN_RANGE(lambda_b, range_min, range_max)) {
return true;
}
- else if (isect_ray_seg_v3(v_a_co, v_a_b_dir, l_b->prev->v->co, l_b->next->v->co, &lambda)) {
- return IN_RANGE(lambda, 0.0f, 1.0f);
+ else {
+ copy_v3_v3(co, l_b->prev->v->co);
+ sub_v3_v3v3(dir, l_b->next->v->co, co);
+ if (isect_ray_ray_v3(v_a_co, v_a_b_dir, co, dir, &lambda_a, &lambda_b)) {
+ return IN_RANGE(lambda_a, range_min, range_max) &&
+ IN_RANGE(lambda_b, range_min, range_max);
+ }
}
}
return false;
}
-void BM_vert_weld_linked_wire_edges_into_linked_faces(
- BMesh *bm, BMVert *v, const float epsilon, BMEdge **r_edgenet[], int *r_edgenet_alloc_len)
+static BMFace *bm_vert_pair_best_face_get(
+ BMVert *v_a, BMVert *v_b, BMEdge **edgenet, const int edgenet_len, const float epsilon)
{
- BMEdge **edgenet = *r_edgenet;
- int edgenet_alloc_len = *r_edgenet_alloc_len;
-
- BMIter iter;
- BMEdge *e;
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- int edgenet_len = 0;
- BMVert *v_other = v;
- while (BM_edge_is_wire(e)) {
- if (edgenet_alloc_len == edgenet_len) {
- edgenet_alloc_len = (edgenet_alloc_len + 1) * 2;
- edgenet = MEM_reallocN(edgenet, (edgenet_alloc_len) * sizeof(*edgenet));
- }
- edgenet[edgenet_len++] = e;
- v_other = BM_edge_other_vert(e, v_other);
- if (v_other == v) {
- /* Endless loop. */
- break;
- }
-
- BMEdge *e_next = BM_DISK_EDGE_NEXT(e, v_other);
- if (e_next == e) {
- /* Vert is wire_endpoint. */
- edgenet_len = 0;
- break;
- }
-
- BMEdge *e_test = e_next;
- while ((e_test = BM_DISK_EDGE_NEXT(e_test, v_other)) != e) {
- if (e_test->l) {
- /* Vert is linked to a face. */
- goto l_break;
- }
- }
-
- e = e_next;
- }
-
- BMLoop *dummy;
- BMFace *best_face;
+ BMFace *r_best_face = NULL;
- l_break:
- if (edgenet_len == 0) {
- /* Nothing to do. */
- continue;
- }
- if (edgenet_len == 1) {
- float data[2][3];
- copy_v3_v3(data[0], v_other->co);
- sub_v3_v3v3(data[1], v->co, data[0]);
- best_face = BM_vert_pair_shared_face_cb(
- v_other, v, true, bm_vert_pair_share_splittable_face_cb, &data, &dummy, &dummy);
- }
- else {
- struct EDBMSplitBestFaceData data = {
- .edgenet = edgenet,
- .edgenet_len = edgenet_len,
- .best_face_range_on_normal_axis = FLT_MAX,
- .r_best_face = NULL,
- };
- BM_vert_pair_shared_face_cb(
- v_other, v, true, bm_vert_pair_share_best_splittable_face_cb, &data, &dummy, &dummy);
-
- if (data.r_best_face) {
- float no[3], min = FLT_MAX, max = -FLT_MAX;
- copy_v3_v3(no, data.r_best_face->no);
- BMVert *v_test;
- BMIter f_iter;
- BM_ITER_ELEM (v_test, &f_iter, data.r_best_face, BM_VERTS_OF_FACE) {
- float dot = dot_v3v3(v_test->co, no);
- if (dot < min) {
- min = dot;
- }
- if (dot > max) {
- max = dot;
- }
+ BMLoop *dummy;
+ if (edgenet_len == 1) {
+ float data[2][3];
+ copy_v3_v3(data[0], v_b->co);
+ sub_v3_v3v3(data[1], v_a->co, data[0]);
+ r_best_face = BM_vert_pair_shared_face_cb(
+ v_a, v_b, false, bm_vert_pair_share_splittable_face_cb, &data, &dummy, &dummy);
+ }
+ else {
+ struct EDBMSplitBestFaceData data = {
+ .edgenet = edgenet,
+ .edgenet_len = edgenet_len,
+ .best_edgenet_range_on_face_normal = FLT_MAX,
+ .r_best_face = NULL,
+ };
+ BM_vert_pair_shared_face_cb(
+ v_a, v_b, true, bm_vert_pair_share_best_splittable_face_cb, &data, &dummy, &dummy);
+
+ if (data.r_best_face) {
+ /* Check if the edgenet's range is smaller than the face's range. */
+ float no[3], min = FLT_MAX, max = -FLT_MAX;
+ copy_v3_v3(no, data.r_best_face->no);
+ BMVert *v_test;
+ BMIter f_iter;
+ BM_ITER_ELEM (v_test, &f_iter, data.r_best_face, BM_VERTS_OF_FACE) {
+ float dot = dot_v3v3(v_test->co, no);
+ if (dot < min) {
+ min = dot;
}
- float range = max - min + 2 * epsilon;
- if (range < data.best_face_range_on_normal_axis) {
- data.r_best_face = NULL;
+ if (dot > max) {
+ max = dot;
}
}
- best_face = data.r_best_face;
- }
-
- if (best_face) {
- BM_face_split_edgenet(bm, best_face, edgenet, edgenet_len, NULL, NULL);
+ float face_range_on_normal = max - min + 2 * epsilon;
+ if (face_range_on_normal < data.best_edgenet_range_on_face_normal) {
+ data.r_best_face = NULL;
+ }
}
+ r_best_face = data.r_best_face;
}
- *r_edgenet = edgenet;
- *r_edgenet_alloc_len = edgenet_alloc_len;
+ return r_best_face;
}
/** \} */
@@ -517,7 +485,8 @@ static int sort_cmp_by_lambda_cb(const void *index1_v, const void *index2_v, voi
#define INTERSECT_EDGES
-bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHash *r_targetmap)
+bool BM_mesh_intersect_edges(
+ BMesh *bm, const char hflag, const float dist, const bool split_faces, GHash *r_targetmap)
{
bool ok = false;
@@ -560,6 +529,9 @@ bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHas
verts_remain_len++;
}
}
+
+ /* The index will indicate which cut in pair_array this vertex belongs to. */
+ BM_elem_index_set(v, -1);
}
bm->elem_index_dirty |= BM_VERT;
@@ -621,6 +593,10 @@ bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHas
/* Don't test hidden edges or smaller than the minimum distance.
* These have already been handled in the vertices overlap. */
BM_elem_index_set(e, 0);
+ if (split_faces) {
+ /* Tag to be ignored. */
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
continue;
}
@@ -631,6 +607,10 @@ bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHas
else {
BM_elem_index_set(e, EDGE_REMAIN_TO_TEST);
edges_remain_len++;
+ if (split_faces) {
+ /* Tag to be ignored. */
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
}
}
@@ -823,6 +803,11 @@ bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHas
lambda = (pair_elem->lambda - lambda_prev) / (1.0f - lambda_prev);
lambda_prev = pair_elem->lambda;
e = pair_elem->edge;
+ if (split_faces) {
+ /* Tagged edges are ignored when split faces.
+ /* Untag these. */
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
BMVert *v_new = BM_edge_split(bm, e, e->v1, NULL, lambda);
pair_elem->vert = v_new;
@@ -856,10 +841,136 @@ bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHas
BLI_assert((*pair_iter)[0].elem->head.htype == BM_VERT);
BLI_assert((*pair_iter)[1].elem->head.htype == BM_VERT);
BLI_assert((*pair_iter)[0].elem != (*pair_iter)[1].elem);
-
- BLI_ghash_insert(r_targetmap, (*pair_iter)[0].vert, (*pair_iter)[1].vert);
+ BMVert *v_key, *v_val;
+ v_key = (*pair_iter)[0].vert;
+ v_val = (*pair_iter)[1].vert;
+ BLI_ghash_insert(r_targetmap, v_key, v_val);
+ if (split_faces) {
+ BM_elem_index_set(v_key, i * 2);
+ BM_elem_index_set(v_val, i * 2 + 1);
+ }
}
+ if (split_faces) {
+ BMEdge **edgenet = NULL;
+ int edgenet_alloc_len = 0;
+
+ struct EDBMSplitElem *pair_flat = (struct EDBMSplitElem *)&pair_array[0];
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ continue;
+ }
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+
+ BMVert *va, *vb, *va_dest = NULL;
+ va = e->v1;
+ vb = e->v2;
+
+ int v_cut = BM_elem_index_get(va);
+ int v_cut_other = BM_elem_index_get(vb);
+ if (v_cut == -1 && v_cut_other == -1) {
+ continue;
+ }
+
+ if (v_cut == -1) {
+ SWAP(BMVert *, va, vb);
+ v_cut = v_cut_other;
+ v_cut_other = -1;
+ }
+
+ v_cut += v_cut % 2 ? -1 : 1;
+ va_dest = pair_flat[v_cut].vert;
+
+ BMFace *best_face = NULL;
+ int edgenet_len = 0;
+ BMVert *v_other_dest, *v_other = vb;
+ BMEdge *e_net = e;
+ while (true) {
+ if (edgenet_alloc_len == edgenet_len) {
+ edgenet_alloc_len = (edgenet_alloc_len + 1) * 2;
+ edgenet = MEM_reallocN(edgenet, (edgenet_alloc_len) * sizeof(*edgenet));
+ }
+ edgenet[edgenet_len++] = e_net;
+
+ if (v_cut_other != -1) {
+ v_cut_other += v_cut_other % 2 ? -1 : 1;
+ v_other_dest = pair_flat[v_cut_other].vert;
+ }
+ else {
+ v_other_dest = v_other;
+ }
+
+ best_face = bm_vert_pair_best_face_get(
+ va_dest, v_other_dest, edgenet, edgenet_len, dist);
+
+ if (best_face) {
+ if (va_dest != va) {
+ e_net = edgenet[0];
+ if (edgenet_len > 1) {
+ vb = BM_edge_other_vert(e_net, va);
+ }
+ else {
+ vb = v_other_dest;
+ }
+ edgenet[0] = BM_edge_create(bm, va_dest, vb, e_net, BM_CREATE_NOP);
+ }
+ if ((edgenet_len > 1) && (v_other_dest != v_other)) {
+ e_net = edgenet[edgenet_len - 1];
+ edgenet[edgenet_len - 1] = BM_edge_create(
+ bm, v_other_dest, BM_edge_other_vert(e_net, v_other), e_net, BM_CREATE_NOP);
+ }
+ break;
+ }
+
+ BMEdge *e_test = e_net, *e_next = NULL;
+ while ((e_test = BM_DISK_EDGE_NEXT(e_test, v_other)) != (e_net)) {
+ if (!BM_edge_is_wire(e_test)) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ continue;
+ }
+ if (BM_elem_index_get(e_test->v1) == -1 && BM_elem_index_get(e_test->v2) == -1) {
+ continue;
+ }
+ }
+ else if (!BM_edge_is_wire(e_net)) {
+ continue;
+ }
+ e_next = e_test;
+ break;
+ }
+
+ if (e_next == NULL) {
+ break;
+ }
+
+ e_net = e_next;
+ v_other = BM_edge_other_vert(e_net, v_other);
+ if (v_other == va) {
+ /* Endless loop. */
+ break;
+ }
+ v_cut_other = BM_elem_index_get(v_other);
+ }
+
+ if (best_face) {
+ BMFace **face_arr = NULL;
+ int face_arr_len = 0;
+ BM_face_split_edgenet(bm, best_face, edgenet, edgenet_len, &face_arr, &face_arr_len);
+ if (face_arr) {
+ /* Update the new faces normal.
+ * Normal is necessary to obtain the best face for edgenet */
+ while (face_arr_len--) {
+ BM_face_normal_update(face_arr[face_arr_len]);
+ }
+ MEM_freeN(face_arr);
+ }
+ }
+ }
+
+ if (edgenet) {
+ MEM_freeN(edgenet);
+ }
+ }
ok = true;
}
}
diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.h b/source/blender/bmesh/tools/bmesh_intersect_edges.h
index a22a1ca1e1d..7e2252250d6 100644
--- a/source/blender/bmesh/tools/bmesh_intersect_edges.h
+++ b/source/blender/bmesh/tools/bmesh_intersect_edges.h
@@ -21,9 +21,7 @@
#ifndef __BMESH_INTERSECT_EDGES_H__
#define __BMESH_INTERSECT_EDGES_H__
-void BM_vert_weld_linked_wire_edges_into_linked_faces(
- BMesh *bm, BMVert *v, const float epsilon, BMEdge **r_edgenet[], int *r_edgenet_alloc_len);
-
-bool BM_mesh_intersect_edges(BMesh *bm, const char hflag, const float dist, GHash *r_targetmap);
+bool BM_mesh_intersect_edges(
+ BMesh *bm, const char hflag, const float dist, const bool split_faces, GHash *r_targetmap);
#endif /* __BMESH_INTERSECT_EDGES_H__ */