[Bf-blender-cvs] [416afcb1c37] sculpt-dev: Sculpt: Move geodesic distances code to its own file

Pablo Dobarro noreply at git.blender.org
Mon Feb 15 22:56:53 CET 2021


Commit: 416afcb1c37ba541ac5c2d18dd5d97a172cc597b
Author: Pablo Dobarro
Date:   Mon Feb 15 19:11:49 2021 +0100
Branches: sculpt-dev
https://developer.blender.org/rB416afcb1c37ba541ac5c2d18dd5d97a172cc597b

Sculpt: Move geodesic distances code to its own file

===================================================================

M	source/blender/editors/sculpt_paint/CMakeLists.txt
M	source/blender/editors/sculpt_paint/sculpt.c
A	source/blender/editors/sculpt_paint/sculpt_geodesic.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 025fa6b0697..0d36d666ed7 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -66,6 +66,7 @@ set(SRC
   sculpt_filter_color.c
   sculpt_filter_mask.c
   sculpt_filter_mesh.c
+  sculpt_geodesic.c
   sculpt_gradient.c
   sculpt_mask_expand.c
   sculpt_multiplane_scrape.c
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 3229b67ae9a..fd90506f103 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -10471,266 +10471,7 @@ static void SCULPT_OT_mask_init(wmOperatorType *ot)
                "");
 }
 
-#define SCULPT_GEODESIC_VERTEX_NONE -1
 
-static bool sculpt_geodesic_mesh_test_dist_add(
-    MVert *mvert, const int v0, const int v1, const int v2, float *dists, GSet *initial_vertices)
-{
-  if (BLI_gset_haskey(initial_vertices, POINTER_FROM_INT(v0))) {
-    return false;
-  }
-
-  BLI_assert(dists[v1] != FLT_MAX);
-  if (dists[v0] <= dists[v1]) {
-    return false;
-  }
-
-  float dist0;
-  if (v2 != SCULPT_GEODESIC_VERTEX_NONE) {
-    BLI_assert(dists[v2] != FLT_MAX);
-    if (dists[v0] <= dists[v2]) {
-      return false;
-    }
-    dist0 = geodesic_distance_propagate_across_triangle(
-        mvert[v0].co, mvert[v1].co, mvert[v2].co, dists[v1], dists[v2]);
-  }
-  else {
-    float vec[3];
-    sub_v3_v3v3(vec, mvert[v1].co, mvert[v0].co);
-    dist0 = dists[v1] + len_v3(vec);
-  }
-
-  if (dist0 < dists[v0]) {
-    dists[v0] = dist0;
-    return true;
-  }
-
-  return false;
-}
-
-static float *SCULPT_geodesic_mesh_create(Object *ob,
-                                          GSet *initial_vertices,
-                                          const float limit_radius)
-{
-  SculptSession *ss = ob->sculpt;
-  Mesh *mesh = BKE_object_get_original_mesh(ob);
-
-  const int totvert = mesh->totvert;
-  const int totedge = mesh->totedge;
-
-  const float limit_radius_sq = limit_radius * limit_radius;
-
-  MEdge *edges = mesh->medge;
-  MVert *verts = SCULPT_mesh_deformed_mverts_get(ss);
-
-  float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "distances");
-  BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag");
-
-  if (!ss->epmap) {
-    BKE_mesh_edge_poly_map_create(&ss->epmap,
-                                  &ss->epmap_mem,
-                                  mesh->medge,
-                                  mesh->totedge,
-                                  mesh->mpoly,
-                                  mesh->totpoly,
-                                  mesh->mloop,
-                                  mesh->totloop);
-  }
-  if (!ss->vemap) {
-    BKE_mesh_vert_edge_map_create(
-        &ss->vemap, &ss->vemap_mem, mesh->medge, mesh->totvert, mesh->totedge);
-  }
-
-  BLI_LINKSTACK_DECLARE(queue, int);
-  BLI_LINKSTACK_DECLARE(queue_next, int);
-
-  BLI_LINKSTACK_INIT(queue);
-  BLI_LINKSTACK_INIT(queue_next);
-
-  for (int i = 0; i < totvert; i++) {
-    if (BLI_gset_haskey(initial_vertices, POINTER_FROM_INT(i))) {
-      dists[i] = 0.0f;
-    }
-    else {
-      dists[i] = FLT_MAX;
-    }
-  }
-
-  BLI_bitmap *affected_vertex = BLI_BITMAP_NEW(totvert, "affected vertex");
-  GSetIterator gs_iter;
-  GSET_ITER (gs_iter, initial_vertices) {
-    const int v = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter));
-    float *v_co = verts[v].co;
-    for (int i = 0; i < totvert; i++) {
-      if (len_squared_v3v3(v_co, verts[i].co) <= limit_radius_sq) {
-        BLI_BITMAP_ENABLE(affected_vertex, i);
-      }
-    }
-  }
-
-  for (int i = 0; i < totedge; i++) {
-    const int v1 = edges[i].v1;
-    const int v2 = edges[i].v2;
-    if (!BLI_BITMAP_TEST(affected_vertex, v1) && !BLI_BITMAP_TEST(affected_vertex, v2)) {
-      continue;
-    }
-    if (dists[v1] != FLT_MAX || dists[v2] != FLT_MAX) {
-      BLI_LINKSTACK_PUSH(queue, i);
-    }
-  }
-
-  do {
-    int e;
-    while (e = BLI_LINKSTACK_POP(queue)) {
-      int v1 = edges[e].v1;
-      int v2 = edges[e].v2;
-
-      if (dists[v1] == FLT_MAX || dists[v2] == FLT_MAX) {
-        if (dists[v1] > dists[v2]) {
-          SWAP(int, v1, v2);
-        }
-        sculpt_geodesic_mesh_test_dist_add(
-            verts, v2, v1, SCULPT_GEODESIC_VERTEX_NONE, dists, initial_vertices);
-      }
-
-      if (ss->epmap[e].count != 0) {
-        for (int pi = 0; pi < ss->epmap[e].count; pi++) {
-          const int poly = ss->epmap[e].indices[pi];
-          if (ss->face_sets[poly] <= 0) {
-            continue;
-          }
-          const MPoly *mpoly = &mesh->mpoly[poly];
-
-          for (int li = 0; li < mpoly->totloop; li++) {
-            const MLoop *mloop = &mesh->mloop[li + mpoly->loopstart];
-            const int v_other = mloop->v;
-            if (ELEM(v_other, v1, v2)) {
-              continue;
-            }
-            if (sculpt_geodesic_mesh_test_dist_add(
-                    verts, v_other, v1, v2, dists, initial_vertices)) {
-              for (int ei = 0; ei < ss->vemap[v_other].count; ei++) {
-                const int e_other = ss->vemap[v_other].indices[ei];
-                int ev_other;
-                if (edges[e_other].v1 == v_other) {
-                  ev_other = edges[e_other].v2;
-                }
-                else {
-                  ev_other = edges[e_other].v1;
-                }
-
-                if (e_other != e && !BLI_BITMAP_TEST(edge_tag, e_other) &&
-                    (ss->epmap[e_other].count == 0 || dists[ev_other] != FLT_MAX)) {
-                  if (BLI_BITMAP_TEST(affected_vertex, v_other) ||
-                      BLI_BITMAP_TEST(affected_vertex, ev_other)) {
-                    BLI_BITMAP_ENABLE(edge_tag, e_other);
-                    BLI_LINKSTACK_PUSH(queue_next, e_other);
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-
-    for (LinkNode *lnk = queue_next; lnk; lnk = lnk->next) {
-      const int e = POINTER_AS_INT(lnk->link);
-      BLI_BITMAP_DISABLE(edge_tag, e);
-    }
-
-    BLI_LINKSTACK_SWAP(queue, queue_next);
-
-  } while (BLI_LINKSTACK_SIZE(queue));
-
-  BLI_LINKSTACK_FREE(queue);
-  BLI_LINKSTACK_FREE(queue_next);
-  MEM_SAFE_FREE(edge_tag);
-  MEM_SAFE_FREE(affected_vertex);
-
-  return dists;
-}
-
-static float *SCULPT_geodesic_fallback_create(Object *ob, GSet *initial_vertices)
-{
-
-  SculptSession *ss = ob->sculpt;
-  Mesh *mesh = BKE_object_get_original_mesh(ob);
-  const int totvert = mesh->totvert;
-  float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "distances");
-  int first_affected = SCULPT_GEODESIC_VERTEX_NONE;
-  GSetIterator gs_iter;
-  GSET_ITER (gs_iter, initial_vertices) {
-    first_affected = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter));
-    break;
-  }
-  if (first_affected == SCULPT_GEODESIC_VERTEX_NONE) {
-    return dists;
-  }
-
-  const float *first_affected_co = SCULPT_vertex_co_get(ss, first_affected);
-  for (int i = 0; i < totvert; i++) {
-    dists[i] = len_v3v3(first_affected_co, SCULPT_vertex_co_get(ss, i));
-  }
-
-  return dists;
-}
-
-float *SCULPT_geodesic_distances_create(Object *ob,
-                                        GSet *initial_vertices,
-                                        const float limit_radius)
-{
-  SculptSession *ss = ob->sculpt;
-  switch (BKE_pbvh_type(ss->pbvh)) {
-    case PBVH_FACES:
-      return SCULPT_geodesic_mesh_create(ob, initial_vertices, limit_radius);
-    case PBVH_BMESH:
-    case PBVH_GRIDS:
-      return SCULPT_geodesic_fallback_create(ob, initial_vertices);
-  }
-  BLI_assert(false);
-  return NULL;
-}
-
-float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd,
-                                            Object *ob,
-                                            const int vertex,
-                                            const float limit_radius)
-{
-  SculptSession *ss = ob->sculpt;
-  GSet *initial_vertices = BLI_gset_int_new("initial_vertices");
-
-  const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
-  for (char i = 0; i <= symm; ++i) {
-    if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
-      int v = -1;
-      if (i == 0) {
-        v = vertex;
-      }
-      else {
-        float location[3];
-        flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), i);
-        v = SCULPT_nearest_vertex_get(sd, ob, location, FLT_MAX, false);
-      }
-      if (v != -1) {
-        BLI_gset_add(initial_vertices, POINTER_FROM_INT(v));
-      }
-    }
-  }
-
-  float *dists = SCULPT_geodesic_distances_create(ob, initial_vertices, limit_radius);
-  BLI_gset_free(initial_vertices, NULL);
-  return dists;
-}
-
-float *SCULPT_geodesic_from_vertex(Object *ob, const int vertex, const float limit_radius)
-{
-  GSet *initial_vertices = BLI_gset_int_new("initial_vertices");
-  BLI_gset_add(initial_vertices, POINTER_FROM_INT(vertex));
-  float *dists = SCULPT_geodesic_distances_create(ob, initial_vertices, limit_radius);
-  BLI_gset_free(initial_vertices, NULL);
-  return dists;
-}
 
 static int sculpt_reset_brushes_exec(bContext *C, wmOperator *op)
 {
diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
new file mode 100644
index 00000000000..44b242d48e7
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
@@ -0,0 +1,336 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list