[Bf-blender-cvs] [8510c77b9cb] temp_bmesh_multires: Sculpt dyntopo: improve boundary brush for irregular topology (still a wip)

Joseph Eagar noreply at git.blender.org
Mon Aug 16 03:12:13 CEST 2021


Commit: 8510c77b9cbe1d9d90b5471c4bfcef943a30f6ab
Author: Joseph Eagar
Date:   Sun Aug 15 18:02:16 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB8510c77b9cbe1d9d90b5471c4bfcef943a30f6ab

Sculpt dyntopo: improve boundary brush for irregular topology
                (still a wip)

The boundary brush now builds a geodesic distance
  field (from the boundary) from which it derives a tangent
  field:

* These now define the rotation plane for bend mode.
* Rotation origins snap to these planes.

There is also typedef'd code for visualization tangents
in a temporary object (note the sculpt object), to enable
define VISBM in sculpt_boundary.c.  This will be removed
lated.

Additional changes:

* Added a function to get the number of edges around verts,
  SCULPT_vertex_valence_get.
* Added an API to calculate cotangent weights for vert fans,
  SCULPT_cotangents_begin (call in main thread first) and
  SCULPT_get_cotangents.
* Sculpt neighbors for PBVH_FACES now uses ss->vemap if it exists.
* The Mesh topology mapping code now takes extra parameters for
  sorting vert/edge cycles geometrically.
* Similarly, there is now a function to sort BMesh edge cycles,
  BM_sort_disk_cycle.
* MDynTopoVert->flag now has a bitflag for when the disk cycle
  sorting needs to be redone, DYNVERT_NEED_DISK_SORT.
* The sculpt geodesic code now supports passing in custom vertex
  coordinates.
* The geodesic API can also build an optional map of which vertex
  in the initial vertex list is closest to any other vertex.

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

M	extern/quadriflow/src/config.hpp
M	source/blender/blenkernel/BKE_mesh_mapping.h
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/intern/cdderivedmesh.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/blenkernel/intern/mesh_fair.cc
M	source/blender/blenkernel/intern/mesh_mapping.c
M	source/blender/blenkernel/intern/mesh_merge.c
M	source/blender/blenkernel/intern/mesh_remap.c
M	source/blender/blenkernel/intern/multires_reshape_apply_base.c
M	source/blender/blenkernel/intern/paint.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/bmesh/intern/bmesh_construct.c
M	source/blender/bmesh/intern/bmesh_construct.h
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_vgroup.c
M	source/blender/editors/sculpt_paint/paint_image_proj.c
M	source/blender/editors/sculpt_paint/paint_vertex.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt_expand.c
M	source/blender/editors/sculpt_paint/sculpt_geodesic.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/makesdna/DNA_meshdata_types.h
M	source/blender/modifiers/intern/MOD_skin.c

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

diff --git a/extern/quadriflow/src/config.hpp b/extern/quadriflow/src/config.hpp
index bf597ad0f39..106a8e58d0b 100644
--- a/extern/quadriflow/src/config.hpp
+++ b/extern/quadriflow/src/config.hpp
@@ -1,6 +1,8 @@
 #ifndef CONFIG_H_
 #define CONFIG_H_
 
+#define WITH_OMP
+
 /* Workaround a bug in boost 1.68, until we upgrade to a newer version. */
 #if defined(__clang__) && defined(WIN32)
   #include <boost/type_traits/is_assignable.hpp>
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 0518f303744..c958d01a849 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -105,20 +105,28 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly,
 UvMapVert *BKE_mesh_uv_vert_map_get_vert(UvVertMap *vmap, unsigned int v);
 void BKE_mesh_uv_vert_map_free(UvVertMap *vmap);
 
-void BKE_mesh_vert_poly_map_create(MeshElemMap **r_map,
-                                   int **r_mem,
-                                   const struct MPoly *mpoly,
-                                   const struct MLoop *mloop,
-                                   int totvert,
-                                   int totpoly,
-                                   int totloop);
-void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map,
-                                   int **r_mem,
-                                   const struct MPoly *mpoly,
-                                   const struct MLoop *mloop,
-                                   int totvert,
-                                   int totpoly,
-                                   int totloop);
+void BKE_mesh_vert_poly_map_create(
+    MeshElemMap **r_map,
+    int **r_mem,
+    const struct MVert *mvert,  // only needed if sort_disk_cycles is true
+    const struct MEdge *medge,  // only needed if sort_disk_cycles is true
+    const struct MPoly *mpoly,
+    const struct MLoop *mloop,
+    int totvert,
+    int totpoly,
+    int totloop,
+    const bool sort_disk_cycles);  // put polys in sorted geometric order
+void BKE_mesh_vert_loop_map_create(
+    MeshElemMap **r_map,
+    int **r_mem,
+    const struct MVert *mvert,  // only needed if sort_disk_cycles is true
+    const struct MEdge *medge,  // only needed if sort_disk_cycles is true
+    const struct MPoly *mpoly,
+    const struct MLoop *mloop,
+    int totvert,
+    int totpoly,
+    int totloop,
+    const bool sort_disk_cycles);  // put loops in sorted geometric order
 void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
                                       int **r_mem,
                                       const struct MVert *mvert,
@@ -128,7 +136,13 @@ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map,
                                       const struct MLoop *mloop,
                                       const int totloop);
 void BKE_mesh_vert_edge_map_create(
-    MeshElemMap **r_map, int **r_mem, const struct MEdge *medge, int totvert, int totedge);
+    MeshElemMap **r_map,
+    int **r_mem,
+    const struct MVert *mvert,  // only needed if sort_disk_cycles is true
+    const struct MEdge *medge,
+    int totvert,
+    int totedge,
+    bool sort_disk_cycles);  // sort verts in geometric order around edges
 void BKE_mesh_vert_edge_vert_map_create(
     MeshElemMap **r_map, int **r_mem, const struct MEdge *medge, int totvert, int totedge);
 void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 1dcd21448df..7314a2dc8ff 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -383,6 +383,14 @@ typedef struct SculptBoundaryPreviewEdge {
   SculptVertRef v2;
 } SculptBoundaryPreviewEdge;
 
+#define MAX_STORED_COTANGENTW_EDGES 7
+
+typedef struct StoredCotangentW {
+  float static_weights[MAX_STORED_COTANGENTW_EDGES];
+  float *weights;
+  int length;
+} StoredCotangentW;
+
 typedef struct SculptBoundary {
   /* Vertex indices of the active boundary. */
   SculptVertRef *vertices;
@@ -396,6 +404,14 @@ typedef struct SculptBoundary {
    * a distance of 0. */
   float *distance;
 
+  float (*smoothco)[3];
+  float *boundary_dist;  // distances from verts to boundary
+  float (*boundary_tangents)[3];
+
+  StoredCotangentW *boundary_cotangents;
+  SculptVertRef *boundary_closest;
+  int sculpt_totvert;
+
   /* Data for drawing the preview. */
   SculptBoundaryPreviewEdge *edges;
   int edges_capacity;
@@ -469,8 +485,9 @@ typedef struct SculptSession {
 
   /* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
   struct MVert *mvert;
-  struct MPoly *mpoly;
+  struct MEdge *medge;
   struct MLoop *mloop;
+  struct MPoly *mpoly;
 
   // only assigned in PBVH_FACES and PBVH_GRIDS
   CustomData *vdata, *edata, *ldata, *pdata;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 039a971fe2c..8c3ec0b2ff8 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -171,8 +171,16 @@ static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
   if (!cddm->pmap && ob->type == OB_MESH) {
     Mesh *me = ob->data;
 
-    BKE_mesh_vert_poly_map_create(
-        &cddm->pmap, &cddm->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
+    BKE_mesh_vert_poly_map_create(&cddm->pmap,
+                                  &cddm->pmap_mem,
+                                  me->mvert,
+                                  me->medge,
+                                  me->mpoly,
+                                  me->mloop,
+                                  me->totvert,
+                                  me->totpoly,
+                                  me->totloop,
+                                  false);
   }
 
   return cddm->pmap;
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index ed5add38414..3f36aa2b430 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -2014,6 +2014,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx,
 
   MDynTopoVert *mv_new = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_new);
   bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v_new);
+  mv_new->flag |= DYNVERT_NEED_DISK_SORT;
 }
 
 static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx,
@@ -2410,6 +2411,7 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
     MDynTopoVert *mv_conn = BKE_PBVH_DYNVERT(pbvh->cd_dyn_vert, v_conn);
 
     bke_pbvh_update_vert_boundary(pbvh->cd_dyn_vert, pbvh->cd_faceset_offset, v_conn);
+    mv_conn->flag |= DYNVERT_NEED_DISK_SORT;
   }
 
   /* Delete v_del */
diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc
index 6ac1aa9b2b9..89edda6e306 100644
--- a/source/blender/blenkernel/intern/mesh_fair.cc
+++ b/source/blender/blenkernel/intern/mesh_fair.cc
@@ -213,11 +213,14 @@ class MeshFairingContext : public FairingContext {
     mloop_ = mesh->mloop;
     BKE_mesh_vert_loop_map_create(&vlmap_,
                                   &vlmap_mem_,
+                                  mesh->mvert,
+                                  mesh->medge,
                                   mesh->mpoly,
                                   mesh->mloop,
                                   mesh->totvert,
                                   mesh->totpoly,
-                                  mesh->totloop);
+                                  mesh->totloop,
+                                  false);
 
     /* Deformation coords. */
     co_.reserve(mesh->totvert);
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index d28bb9c0744..67bb14a6212 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -26,12 +26,16 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_vec_types.h"
 
+#include "BLI_alloca.h"
 #include "BLI_bitmap.h"
 #include "BLI_buffer.h"
 #include "BLI_math.h"
+#include "BLI_sort.h"
+#include "BLI_sort_utils.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_customdata.h"
+#include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
 #include "BLI_memarena.h"
 
@@ -194,6 +198,270 @@ void BKE_mesh_uv_vert_map_free(UvVertMap *vmap)
   }
 }
 
+typedef struct DiskCycleSortData {
+  float th;
+  int i, elem;
+  const float *co;
+} DiskCycleSortData;
+
+/**
+ * Calculate a normal from a vertex cloud.
+ *
+ * \note We could make a higher quality version that takes all vertices into account.
+ * Currently it finds 4 outer most points returning its normal.
+ */
+static void calc_cloud_normal(DiskCycleSortData *varr,
+                              int varr_len,
+                              float r_normal[3],
+                              float r_center[3],
+                              int *r_index_tangent)
+{
+  const float varr_len_inv = 1.0f / (float)varr_len;
+
+  /* Get the center point and collect vector array since we loop over these a lot. */
+  float center[3] = {0.0f, 0.0f, 0.0f};
+  for (int i = 0; i < varr_len; i++) {
+    madd_v3_v3fl(center, varr[i].co, varr_len_inv);
+  }
+
+  /* Find the 'co_a' point from center. */
+  int co_a_index = 0;
+  const float *co_a = NULL;
+  {
+    float dist_sq_max = -1.0f;
+    for (int i = 0; i < varr_len; i++) {
+      const float dist_sq_test = len_squared_v3v3(varr[i].co, center);
+      if (!(dist_sq_test <= dist_sq_max)) {
+        co_a = varr[i].co;
+        co_a_index = i;
+        dist_sq_max = dist_sq_test;
+      }
+    }
+  }
+
+  float dir_a[3];
+  sub_v3_v3v3(dir_a, co_a, center);
+  normalize_v3(dir_a);
+
+  const float *co_b = NULL;
+  float dir_b[3] = {0.0f, 0.0f, 0.0f};
+  {
+    float dist_sq_max = -1.0f;
+    for (int i = 0; i < varr_len; i++) {
+      if (varr[i].co == co_a) {
+        continue;
+      }
+      float dir_test[3];
+      sub_v3_v3v3(dir_test, varr[i].co, center);
+      project_plane_normalized_v3_v3v3(dir_test, dir_test, dir_a);
+      const fl

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list