[Bf-blender-cvs] [230ff389461] newboolean: Coplanar case works except CDT makes a face with repeated vert.
Howard Trickey
noreply at git.blender.org
Mon Dec 2 15:05:27 CET 2019
Commit: 230ff389461eaf425ecd0fdf15a4056868071eb4
Author: Howard Trickey
Date: Tue Oct 8 07:34:55 2019 -0400
Branches: newboolean
https://developer.blender.org/rB230ff389461eaf425ecd0fdf15a4056868071eb4
Coplanar case works except CDT makes a face with repeated vert.
===================================================================
M source/blender/bmesh/tools/bmesh_boolean.c
===================================================================
diff --git a/source/blender/bmesh/tools/bmesh_boolean.c b/source/blender/bmesh/tools/bmesh_boolean.c
index 151626f8bcd..7bee75dd19b 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.c
+++ b/source/blender/bmesh/tools/bmesh_boolean.c
@@ -283,6 +283,18 @@ static int add_int_to_intset(BoolState *bs, IndexedIntSet *intset, int value)
return index;
}
+static bool find_in_intset(const IndexedIntSet *intset, int value)
+{
+ LinkNode *ln;
+
+ for (ln = intset->listhead.list; ln; ln = ln->next) {
+ if (POINTER_AS_INT(ln->link) == value) {
+ return true;
+ }
+ }
+ return false;
+}
+
static int intset_get_value_by_index(const IndexedIntSet *intset, int index)
{
LinkNode *ln;
@@ -753,8 +765,7 @@ static int isect_line_seg_epsilon_v3_db(const double line_v1[3],
cross_v3_v3v3_db(cray, c, a_dir);
fac_b = dot_v3v3_db(cray, crs_ab) / nlen;
- if (fac_b * blen < -epsilon ||
- fac_b * blen - blen > epsilon) {
+ if (fac_b * blen < -epsilon || fac_b * blen - blen > epsilon) {
return 0;
}
else {
@@ -1200,10 +1211,10 @@ static void apply_meshadd_to_bmesh(BMesh *bm,
bmv = bm->vtable[v];
BM_vert_kill(bm, bmv);
#ifdef BOOLDEBUG
- if (dbg_level > 0) {
- printf("killed bmv=%p for vtable[%d]\n", bmv, v);
- /* BM_mesh_validate(bm); */
- }
+ if (dbg_level > 0) {
+ printf("killed bmv=%p for vtable[%d]\n", bmv, v);
+ /* BM_mesh_validate(bm); */
+ }
#endif
}
}
@@ -1278,7 +1289,8 @@ static int meshadd_add_vert(
if (checkdup) {
for (ln = meshadd->verts.list, i = meshadd->vindex_start; ln; ln = ln->next, i++) {
- if (compare_v3v3((float *)ln->link, co, (float)bs->eps)) {
+ newv = (NewVert *)ln->link;
+ if (compare_v3v3(newv->co, co, (float)bs->eps)) {
return i;
}
}
@@ -1308,8 +1320,8 @@ static int meshadd_add_edge(
if (checkdup) {
for (ln = meshadd->edges.list, i = meshadd->eindex_start; ln; ln = ln->next, i++) {
- int *pair = (int *)ln->link;
- if ((pair[0] == v1 && pair[1] == v2) || (pair[0] == v2 && pair[1] == v1)) {
+ newe = (NewEdge *)ln->link;
+ if ((newe->v1 == v1 && newe->v2 == v2) || (newe->v1 == v2 && newe->v2== v1)) {
return i;
}
}
@@ -2005,40 +2017,45 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
ppi = (PartPartIntersect *)ln->link;
for (lnv = ppi->verts.list; lnv; lnv = lnv->next) {
v = POINTER_AS_INT(lnv->link);
- v_index = add_int_to_intset(bs, &verts_needed, v);
- add_to_intintmap(bs, &in_to_vmap, v_index, v);
+ if (!find_in_intset(&verts_needed, v)) {
+ v_index = add_int_to_intset(bs, &verts_needed, v);
+ add_to_intintmap(bs, &in_to_vmap, v_index, v);
+ }
}
for (lne = ppi->edges.list; lne; lne = lne->next) {
e = POINTER_AS_INT(lne->link);
- imeshplus_get_edge_verts(&imp, e, &v1, &v2);
- BLI_assert(v1 != -1 && v2 != -1);
- v_index = add_int_to_intset(bs, &verts_needed, v1);
- add_to_intintmap(bs, &in_to_vmap, v_index, v1);
- v_index = add_int_to_intset(bs, &verts_needed, v2);
- add_to_intintmap(bs, &in_to_vmap, v_index, v2);
- e_index = add_int_to_intset(bs, &edges_needed, e);
- add_to_intintmap(bs, &in_to_emap, e_index, e);
+ if (!find_in_intset(&edges_needed, e)) {
+ imeshplus_get_edge_verts(&imp, e, &v1, &v2);
+ BLI_assert(v1 != -1 && v2 != -1);
+ v_index = add_int_to_intset(bs, &verts_needed, v1);
+ add_to_intintmap(bs, &in_to_vmap, v_index, v1);
+ v_index = add_int_to_intset(bs, &verts_needed, v2);
+ add_to_intintmap(bs, &in_to_vmap, v_index, v2);
+ e_index = add_int_to_intset(bs, &edges_needed, e);
+ add_to_intintmap(bs, &in_to_emap, e_index, e);
+ }
}
for (lnf = ppi->faces.list; lnf; lnf = lnf->next) {
f = POINTER_AS_INT(lnf->link);
- face_len = imeshplus_facelen(&imp, f);
- nfaceverts += face_len;
-#if 0
-/* maybe do this in code that made coplanar ppi? */
- for (j = 0; j < face_len; j++) {
- v = imesh_face_vert(im, f, j);
- BLI_assert(v != -1);
- v_index = add_int_to_intset(bs, &verts_needed, v);
- /* if leave this here, need to check that not adding dups */
- add_to_intintmap(bs, &in_to_vmap, v_index, v);
- }
-#endif
- f_index = add_int_to_intset(bs, &faces_needed, f);
- add_to_intintmap(bs, &in_to_fmap, f_index, f);
+ if (!find_in_intset(&faces_needed, f)) {
+ face_len = imeshplus_facelen(&imp, f);
+ nfaceverts += face_len;
+ for (j = 0; j < face_len; j++) {
+ v = imesh_face_vert(im, f, j);
+ BLI_assert(v != -1);
+ if (!find_in_intset(&verts_needed, v)) {
+ v_index = add_int_to_intset(bs, &verts_needed, v);
+ add_to_intintmap(bs, &in_to_vmap, v_index, v);
+ }
+ }
+ f_index = add_int_to_intset(bs, &faces_needed, f);
+ add_to_intintmap(bs, &in_to_fmap, f_index, f);
+ }
}
}
/* Edges implicit in faces will come back as orig edges, so handle those. */
tot_ne = edges_needed.size;
+#if 0
for (i = 0; i < part_nf; i++) {
f = part_face(part, i);
face_len = imesh_facelen(im, f);
@@ -2050,6 +2067,20 @@ static PartPartIntersect *self_intersect_part_and_ppis(BoolState *bs,
add_to_intintmap(bs, &in_to_emap, j + tot_ne, e);
}
}
+#else
+ for (i = 0; i < faces_needed.size; i++) {
+ f = intset_get_value_by_index(&faces_needed, i);
+ face_len = imesh_facelen(im, f);
+ for (j = 0; j < face_len; j++) {
+ v1 = imesh_face_vert(im, f, j);
+ v2 = imesh_face_vert(im, f, (j + 1) % face_len);
+ e = imesh_find_edge(im, v1, v2);
+ BLI_assert(e != -1);
+ add_to_intintmap(bs, &in_to_emap, j + tot_ne, e);
+ }
+ tot_ne += face_len;
+ }
+#endif
#ifdef BOOLDEBUG
if (dbg_level > 0) {
@@ -2546,12 +2577,12 @@ static PartPartIntersect *coplanar_part_part_intersect(
}
typedef struct FaceEdgeInfo {
- double co[3]; /* coord of this face vertex */
- double isect[3]; /* intersection, if any, of this edge segment (starts at v) with line */
- double factor; /* co = line_co1 + factor * line_dir */
- int v; /* vertex index of this face coord */
- bool v_on; /* is co on the line (within epsilon)? */
- bool isect_ok; /* does this edge segment (excluding end vertex) intersect line? */
+ double co[3]; /* coord of this face vertex */
+ double isect[3]; /* intersection, if any, of this edge segment (starts at v) with line */
+ double factor; /* co = line_co1 + factor * line_dir */
+ int v; /* vertex index of this face coord */
+ bool v_on; /* is co on the line (within epsilon)? */
+ bool isect_ok; /* does this edge segment (excluding end vertex) intersect line? */
} FaceEdgeInfo;
/* Find intersection of a face with a line and return the intervals on line.
@@ -2610,12 +2641,12 @@ static void find_face_line_intersects(BoolState *bs,
fi->factor = len_v3_db(line_co1_to_co) / line_dir_len;
if (dot_v3v3_db(line_co1_to_co, line_dir) < 0.0) {
fi->factor = -fi->factor;
- }
- }
- else {
+ }
+ }
+ else {
zero_v3_db(fi->isect);
fi->factor = 0.0f;
- }
+ }
}
sub_v3_v3v3_db(l_no, line_co2, line_co1);
normalize_v3_d(l_no);
@@ -2623,25 +2654,30 @@ static void find_face_line_intersects(BoolState *bs,
fi = &finfo[i];
if (fi->isect_ok) {
continue;
- }
+ }
finext = &finfo[(i + 1) % flen];
is = isect_line_seg_epsilon_v3_db(
line_co1, line_co2, fi->co, finext->co, eps, fi->isect, &fi->factor, &mu);
if (is > 0) {
fi->isect_ok = true;
if (finext->v_on && is != 2) {
- /* Don't count intersections of only the end of the line segment. */
+ /* Don't count intersections of only the end of the line segment. */
fi->isect_ok = false;
- }
+ }
}
}
#ifdef BOOLDEBUG
if (dbg_level > 0) {
for (i = 0; i < flen; i++) {
fi = &finfo[i];
- printf("finfo[%d]: v=%d v_on=%d isect_ok=%d factor=%g isect=(%f,%f,%f)\n",
- i, fi->v, fi->v_on, fi->isect_ok, fi->factor, F3(fi->isect));
- }
+ printf("finfo[%d]: v=%d v_on=%d isect_ok=%d factor=%g isect=(%f,%f,%f)\n",
+ i,
+ fi->v,
+ fi->v_on,
+ fi->isect_ok,
+ fi->factor,
+ F3(fi->isect));
+ }
}
#endif
/* For now just handle case of convex faces, which should be one of the following
@@ -2657,39 +2693,39 @@ static void find_face_line_intersects(BoolState *bs,
if (finfo[i].isect_ok) {
startpos = i;
break;
- }
- }
- if (startpos == -1) {
+ }
+ }
+ if (startpos == -1) {
#ifdef BOOLDEBUG
if (dbg_level > 0) {
printf("no intersections\n");
return;
- }
+ }
#endif
- }
- endpos = startpos;
- for (i = (startpos + 1) % flen; i != startpos; i = (i + 1) % flen) {
- if (finfo[i].isect_ok) {
- endpos = i;
- }
- }
+ }
+ endpos = startpos;
+ for (i = (startpos + 1) % flen; i != startpos; i = (i + 1) % flen) {
+ if (finfo[i].isect_ok) {
+ endpos = i;
+ }
+ }
#ifdef BOOLDEBUG
- if (dbg_level > 0) {
- printf("startpos=%d, endpos=%d\n", startpos, endpos);
- }
+ if (dbg_level > 0) {
+ printf("startpos=%d, endpos=%d\n", startpos, endpos);
+ }
#endif
interval = BLI_memarena_alloc(bs->mem_arena, 2 * sizeof(double));
- if (finfo[startpos].factor <= finfo[endpos].factor) {
+ if (finfo[startpos].factor <= finfo[endpos].factor) {
interval[0] = finfo[startpos].factor;
interval[1] = finfo[endpos].factor;
- }
- else {
- interval[0] = finfo[endpos].factor;
- interval[1] = finfo[startpos].factor;
- }
- if (interval[1] - interval[0] <= eps) {
- interval[1] = interval[0];
- }
+ }
+ else {
+ interval[0] = finfo[endpos].factor;
+ interval[1] = finfo[startpos].factor;
+ }
+ if (interval[1] - interval[0] <= eps) {
+ interval[1] = interval[0];
+ }
}
#ifdef BOOLDEBUG
printf("interval (dists) = (%f,%f)\n", interval[0], interval[1]);
@@ -2867,7 +2903,9 @@ static PartPartIntersect *non_copla
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list