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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs