[Bf-blender-cvs] [71953aec1a5] newboolean: Refactor to use abstract mesh interface.
Howard Trickey
noreply at git.blender.org
Tue Aug 20 20:18:53 CEST 2019
Commit: 71953aec1a5c47018253736f68f6c8ca2e3aafa4
Author: Howard Trickey
Date: Tue Aug 20 07:00:22 2019 -0400
Branches: newboolean
https://developer.blender.org/rB71953aec1a5c47018253736f68f6c8ca2e3aafa4
Refactor to use abstract mesh interface.
If use abstract mesh interface instead of BMesh then there is hope
that modifier can avoid need to convert to/from BMesh.
===================================================================
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 203a1d10cca..9b02cb9f4d4 100644
--- a/source/blender/bmesh/tools/bmesh_boolean.c
+++ b/source/blender/bmesh/tools/bmesh_boolean.c
@@ -40,7 +40,6 @@
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
-
#include "bmesh.h"
#include "intern/bmesh_private.h"
@@ -48,31 +47,80 @@
#include "BLI_strict_flags.h"
-/* A cluster is a set of coplanar faces (within eps) */
-typedef struct Cluster {
+/* A Mesh Interface.
+ * This would be an abstract interface in C++,
+ * but similate that effect in C.
+ * Idea is to write the rest of the code so that
+ * it will work with either Mesh or BMesh as the
+ * concrete representation.
+ * Thus, editmesh and modifier can use the same
+ * code but without need to convert to BMesh (or Mesh).
+ *
+ * Exactly one of bm and me should be non-null.
+ */
+typedef struct IMesh {
+ BMesh *bm;
+ struct Mesh *me;
+} IMesh;
+
+/* A MeshPart is a subset of the geometry of an IndexMesh.
+ * The indices refer to vertex, edges, and faces in the IndexMesh
+ * that this part is based on (which will be known by context).
+ * Unlike for IndexMesh, the edges implied by faces need not be explicitly
+ * represented here.
+ * Commonly a MeshPart will contain geometry that shares a plane,
+ * and when that is so, the plane member says which plane,
+ * TODO: faster structure for looking up verts, edges, faces.
+ */
+typedef struct MeshPart {
float plane[4]; /* first 3 are normal, 4th is signed distance to plane */
- LinkNode *faces; /* list where links are BMFace* */
-} Cluster;
+ LinkNode *verts; /* links are ints (vert indices) */
+ LinkNode *edges; /* links are ints (edge indices) */
+ LinkNode *faces; /* links are ints (face indices) */
+} MeshPart;
-/* A cluster set is a set of Clusters.
+/* A MeshPartSet set is a set of MeshParts.
* For any two distinct elements of the set, either they are not
* coplanar or if they are, they are known not to intersect.
* TODO: faster structure for looking up by plane.
*/
-typedef struct ClusterSet {
- LinkNode *clusters; /* list where links are Cluster* */
-} ClusterSet;
+typedef struct MeshPartSet {
+ LinkNode *meshparts; /* list where links are MeshParts* */
+ int tot_part;
+} MeshPartSet;
+
+/* A set of integers, where each member gets an index
+ * that can be used to access the member.
+ * TODO: faster structure for lookup.
+ */
+typedef struct IndexedIntSet {
+ LinkNodePair listhead;
+ int size;
+} IndexedIntSet;
+
+/* A result of intersectings parts.
+ * The coordinates in the cdt_result should be turned
+ * back into 3d coords by multplying them by mat_2d_inv,
+ * after putting z_for_inverse into the 3rd component.
+ */
+typedef struct IntersectOutput {
+ CDT_result *cdt_result;
+ float mat_2d_inv[3][3];
+ float z_for_inverse;
+} IntersectOutput;
typedef struct BoolState {
MemArena *mem_arena;
- BLI_mempool *listpool;
- BMesh *bm;
+ IMesh im;
int boolean_mode;
float eps;
- int (*test_fn)(BMFace *f, void *user_data);
+ int (*test_fn)(void *elem, void *user_data);
void *test_fn_user_data;
} BoolState;
+/* test_fn results used to distinguish parts of mesh */
+enum { TEST_B = -1, TEST_NONE = 0, TEST_A = 1, TEST_ALL = 2 };
+
#define BOOLDEBUG
#ifdef BOOLDEBUG
/* For Debugging. */
@@ -82,10 +130,110 @@ typedef struct BoolState {
# define F4(v) (v)[0], (v)[1], (v)[2], (v)[3]
# define BMI(e) BM_elem_index_get(e)
-static void dump_cluster(Cluster *cl, const char *label);
-static void dump_clusterset(ClusterSet *clset, const char *label);
+static void dump_part(MeshPart *part, const char *label);
+static void dump_partset(MeshPartSet *pset, const char *label);
#endif
+static void init_imesh_from_bmesh(IMesh *im, BMesh *bm)
+{
+ im->bm = bm;
+ im->me = NULL;
+ BM_mesh_elem_table_ensure(bm, BM_VERT | BM_EDGE | BM_FACE);
+}
+
+static int imesh_totface(const IMesh *im)
+{
+ if (im->bm) {
+ return im->bm->totface;
+ }
+ else {
+ return 0; /* TODO */
+ }
+}
+
+static int imesh_facelen(const IMesh *im, int f)
+{
+ int ans = 0;
+
+ if (im->bm) {
+ BMFace *bmf = BM_face_at_index(im->bm, f);
+ if (bmf) {
+ ans = bmf->len;
+ }
+ }
+ else {
+ ; /* TODO */
+ }
+ return ans;
+}
+
+static int imesh_face_vert(IMesh *im, int f, int index)
+{
+ int i;
+ int ans = -1;
+
+ if (im->bm) {
+ BMFace *bmf = BM_face_at_index(im->bm, f);
+ if (bmf) {
+ BMLoop *l = bmf->l_first;
+ for (i = 0; i < index; i++) {
+ l = l->next;
+ }
+ BMVert *bmv = l->v;
+ ans = BM_elem_index_get(bmv);
+ }
+ }
+ else {
+ ; /* TODO */
+ }
+ return ans;
+}
+
+static void imesh_get_vert_co(const IMesh *im, int v, float *r_coords)
+{
+ if (im->bm) {
+ BMVert *bmv = BM_vert_at_index(im->bm, v);
+ if (bmv) {
+ copy_v3_v3(r_coords, bmv->co);
+ return;
+ }
+ else {
+ zero_v3(r_coords);
+ }
+ }
+ else {
+ ; /* TODO */
+ }
+}
+
+static void imesh_get_face_plane(const IMesh *im, int f, float r_plane[4])
+{
+ zero_v4(r_plane);
+ if (im->bm) {
+ BMFace *bmf = BM_face_at_index(im->bm, f);
+ if (bmf) {
+ plane_from_point_normal_v3(r_plane, bmf->l_first->v->co, bmf->no);
+ }
+ }
+}
+
+static int imesh_test_face(const IMesh *im, int (*test_fn)(void *, void *), void *user_data, int f)
+{
+ if (im->bm) {
+ BMFace *bmf = BM_face_at_index(im->bm, f);
+ if (bmf) {
+ return test_fn(bmf, user_data);
+ }
+ return 0;
+ }
+ else {
+ /* TODO */
+ return 0;
+ }
+}
+
+
+#if 0
/**
* Make ngon from verts alone.
* Use facerep as example for attributes of new face.
@@ -98,17 +246,54 @@ static BMFace *bool_create_ngon(BMesh *bm, BMVert **vert_arr, const int vert_len
f = BM_face_create_verts(bm, vert_arr, vert_len, facerep, BM_CREATE_NOP, true);
return f;
}
+#endif
-/* Make clusterset by empty. */
-static void init_clusterset(ClusterSet *clusterset)
+static void init_meshpartset(MeshPartSet *partset)
{
- clusterset->clusters = NULL;
+ partset->meshparts = NULL;
+ partset->tot_part = 0;
}
-/* Fill r_plane with the 4d representation of f's plane. */
-static inline void fill_face_plane(float r_plane[4], BMFace *f)
+static void add_part_to_partset(BoolState *bs, MeshPartSet *partset, MeshPart *part)
{
- plane_from_point_normal_v3(r_plane, f->l_first->v->co, f->no);
+ BLI_linklist_prepend_arena(&partset->meshparts, part, bs->mem_arena);
+ partset->tot_part++;
+}
+
+static MeshPart *partset_part(MeshPartSet *partset, int index)
+{
+ LinkNode *ln = BLI_linklist_find(partset->meshparts, index);
+ if (ln) {
+ return (MeshPart *)ln->link;
+ }
+ return NULL;
+}
+
+static void init_meshpart(MeshPart *part)
+{
+ zero_v4(part->plane);
+ part->verts = NULL;
+ part->edges = NULL;
+ part->faces = NULL;
+}
+
+static int part_totface(MeshPart *part)
+{
+ return BLI_linklist_count(part->faces);
+}
+
+static int part_face(MeshPart *part, int index)
+{
+ LinkNode *ln = BLI_linklist_find(part->faces, index);
+ if (ln) {
+ return POINTER_AS_INT(ln->link);
+ }
+ return -1;
+}
+
+static bool parts_may_intersect(MeshPart *part1, MeshPart *part2)
+{
+ return (part1 && part2); /* Placeholder test, uses args */
}
/* Return true if a_plane and b_plane are the same plane, to within eps. */
@@ -120,169 +305,281 @@ static bool planes_are_coplanar(const float a_plane[4], const float b_plane[4],
return fabsf(dot_v3v3(a_plane, b_plane) - 1.0f) <= eps;
}
-/* Return the cluster in clusterset for plane face_plane, if it exists, else NULL. */
-static Cluster *find_cluster_for_plane(BoolState *bs,
- ClusterSet *clusterset,
- const float face_plane[4])
+/* Return the MeshPart in partset for plane.
+ * If none exists, make a new one for the plane and add
+ * it to partset.
+ */
+static MeshPart *find_part_for_plane(BoolState *bs, MeshPartSet *partset, const float plane[4])
{
LinkNode *ln;
+ MeshPart *new_part;
- for (ln = clusterset->clusters; ln; ln = ln->next) {
- Cluster *cl = (Cluster *)ln->link;
- if (planes_are_coplanar(face_plane, cl->plane, bs->eps)) {
- return cl;
+ for (ln = partset->meshparts; ln; ln = ln->next) {
+ MeshPart *p = (MeshPart *)ln->link;
+ if (planes_are_coplanar(plane, p->plane, bs->eps)) {
+ return p;
}
}
- return NULL;
+ new_part = BLI_memarena_alloc(bs->mem_arena, sizeof(MeshPart));
+ init_meshpart(new_part);
+ copy_v4_v4(new_part->plane, plane);
+ add_part_to_partset(bs, partset, new_part);
+ return new_part;
}
-/* Add face f to cluster. */
-static void add_face_to_cluster(BoolState *bs, Cluster *cluster, BMFace *f)
+static void add_face_to_part(BoolState *bs, MeshPart *meshpart, int f)
{
- BLI_linklist_prepend_arena(&cluster->faces, f, bs->mem_arena);
+ BLI_linklist_prepend_arena(&meshpart->faces, POINTER_FROM_INT(f), bs->mem_arena);
}
-/* Make a new cluster containing face f, then add it to clusterset. */
-static void add_new_cluster_to_clusterset(BoolState *bs,
- ClusterSet *clusterset,
- BMFace *f,
- const float plane[4])
+static void init_indexed_intset(IndexedIntSet *intset)
{
- Cluster *new_cluster;
+ intset->listhead.list = NULL;
+ intset->listhead.last_node = NULL;
+ intset->size = 0;
+}
- new_cluster = BLI_memarena_alloc(bs->mem_arena, sizeof(Cluster));
- copy_v4_v4(new_cluster->plane, plane);
- new_cluster->faces = NULL;
- BLI_linklist_prepend_arena(&new_cluster->faces, f, bs->mem_arena);
- BLI_linklist_prepend_arena(&clusterset->clusters, new_cluster, bs->mem_arena);
+static int add_int_to_intset(BoolState *bs, IndexedIntSet *intset, int value)
+{
+ int index;
+
+ index = BLI_linklist_index(intset->listhead.list, POINTER_FROM_INT(value));
+ if (index == -1) {
+ BLI_linklist_append_arena(&intset->listhead, POINTER_FROM_INT(value), bs->mem_arena);
+ index = intset->size;
+ intset->size++;
+ }
+ return index;
}
-/* Add face f to a cluster in clusterset with the same face, else a new cluster for f */
-static void add_
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list