[Bf-blender-cvs] [bc0a0cdf171] master: Multires: Fix Subdivide, Reshape and Apply Base

Sergey Sharybin noreply at git.blender.org
Fri Mar 13 14:25:36 CET 2020


Commit: bc0a0cdf171037cba4076c796e9adb2769382561
Author: Sergey Sharybin
Date:   Tue Mar 3 12:35:51 2020 +0100
Branches: master
https://developer.blender.org/rBbc0a0cdf171037cba4076c796e9adb2769382561

Multires: Fix Subdivide, Reshape and Apply Base

This change fixes artifacts produced by these operations.

On a technical aspect this is done by porting all of the operations
to the new subdivision surface implementation which ensures that
tangent space used to evaluate modifier and those operations is
exactly the same (before modifier will use new code and the operations
will still use an old one).

The next step is to get sculpting on a non-top level to work, and
that actually requires fixes in the undo system.

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

M	source/blender/blenkernel/BKE_multires.h
M	source/blender/blenkernel/BKE_object.h
M	source/blender/blenkernel/CMakeLists.txt
M	source/blender/blenkernel/intern/multires.c
A	source/blender/blenkernel/intern/multires_reshape.c
A	source/blender/blenkernel/intern/multires_reshape.h
A	source/blender/blenkernel/intern/multires_reshape_apply_base.c
A	source/blender/blenkernel/intern/multires_reshape_ccg.c
D	source/blender/blenkernel/intern/multires_reshape_legacy.c
A	source/blender/blenkernel/intern/multires_reshape_smooth.c
A	source/blender/blenkernel/intern/multires_reshape_util.c
A	source/blender/blenkernel/intern/multires_reshape_vertcos.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_relations.c

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

diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index c663ae76564..941675489c1 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -98,16 +98,15 @@ void multiresModifier_del_levels(struct MultiresModifierData *mmd,
                                  struct Scene *scene,
                                  struct Object *object,
                                  int direction);
-void multiresModifier_base_apply(struct MultiresModifierData *mmd,
-                                 struct Scene *scene,
-                                 struct Object *ob);
-void multiresModifier_subdivide(struct MultiresModifierData *mmd,
-                                struct Scene *scene,
-                                struct Object *ob,
-                                int updateblock,
-                                int simple);
-void multiresModifier_sync_levels_ex(struct Scene *scene,
-                                     struct Object *ob_dst,
+void multiresModifier_base_apply(struct Depsgraph *depsgraph,
+                                 struct Object *object,
+                                 struct MultiresModifierData *mmd);
+void multiresModifier_subdivide_legacy(struct MultiresModifierData *mmd,
+                                       struct Scene *scene,
+                                       struct Object *ob,
+                                       int updateblock,
+                                       int simple);
+void multiresModifier_sync_levels_ex(struct Object *ob_dst,
                                      struct MultiresModifierData *mmd_src,
                                      struct MultiresModifierData *mmd_dst);
 
@@ -145,18 +144,32 @@ int mdisp_rot_face_to_crn(struct MVert *mvert,
 
 /* Reshaping, define in multires_reshape.c */
 
+bool multiresModifier_reshapeFromVertcos(struct Depsgraph *depsgraph,
+                                         struct Object *object,
+                                         struct MultiresModifierData *mmd,
+                                         const float (*vert_coords)[3],
+                                         const int num_vert_coords);
 bool multiresModifier_reshapeFromObject(struct Depsgraph *depsgraph,
                                         struct MultiresModifierData *mmd,
                                         struct Object *dst,
                                         struct Object *src);
 bool multiresModifier_reshapeFromDeformModifier(struct Depsgraph *depsgraph,
-                                                struct MultiresModifierData *mmd,
                                                 struct Object *ob,
-                                                struct ModifierData *md);
+                                                struct MultiresModifierData *mmd,
+                                                struct ModifierData *deform_md);
 bool multiresModifier_reshapeFromCCG(const int tot_level,
                                      struct Mesh *coarse_mesh,
                                      struct SubdivCCG *subdiv_ccg);
 
+/* Subdivide multires displacement once. */
+void multiresModifier_subdivide(struct Object *object, struct MultiresModifierData *mmd);
+
+/* Subdivide displacement to the given level.
+ * If level is lower than the current top level nothing happens. */
+void multiresModifier_subdivide_to_level(struct Object *object,
+                                         struct MultiresModifierData *mmd,
+                                         const int top_level);
+
 /* Subdivision integration, defined in multires_subdiv.c */
 
 struct SubdivSettings;
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index a8ebd32ad4d..886591d7728 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -76,9 +76,7 @@ bool BKE_object_shaderfx_use_time(struct Object *ob, struct ShaderFxData *md);
 
 bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifier_type);
 
-void BKE_object_link_modifiers(struct Scene *scene,
-                               struct Object *ob_dst,
-                               const struct Object *ob_src);
+void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_src);
 void BKE_object_free_modifiers(struct Object *ob, const int flag);
 void BKE_object_free_shaderfx(struct Object *ob, const int flag);
 
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 112933e40be..923108240dd 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -168,7 +168,12 @@ set(SRC
   intern/modifier.c
   intern/movieclip.c
   intern/multires.c
-  intern/multires_reshape_legacy.c
+  intern/multires_reshape.c
+  intern/multires_reshape_apply_base.c
+  intern/multires_reshape_ccg.c
+  intern/multires_reshape_smooth.c
+  intern/multires_reshape_util.c
+  intern/multires_reshape_vertcos.c
   intern/multires_subdiv.c
   intern/nla.c
   intern/node.c
@@ -378,6 +383,7 @@ set(SRC
   intern/data_transfer_intern.h
   intern/lib_intern.h
   intern/multires_inline.h
+  intern/multires_reshape.h
   intern/pbvh_intern.h
   intern/subdiv_converter.h
   intern/subdiv_inline.h
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index f3d65f584d1..70061c155d3 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -57,6 +57,8 @@
 
 #include "DEG_depsgraph_query.h"
 
+#include "multires_reshape.h"
+
 #include <math.h>
 #include <string.h>
 
@@ -789,158 +791,7 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene,
   return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags);
 }
 
-/* assumes no is normalized; return value's sign is negative if v is on
- * the other side of the plane */
-static float v3_dist_from_plane(float v[3], float center[3], float no[3])
-{
-  float s[3];
-  sub_v3_v3v3(s, v, center);
-  return dot_v3v3(s, no);
-}
-
-void multiresModifier_base_apply(MultiresModifierData *mmd, Scene *scene, Object *ob)
-{
-  DerivedMesh *cddm, *dispdm, *origdm;
-  Mesh *me;
-  const MeshElemMap *pmap;
-  float(*origco)[3];
-  int i, j, k, offset, totlvl;
-
-  multires_force_sculpt_rebuild(ob);
-
-  me = BKE_mesh_from_object(ob);
-  totlvl = mmd->totlvl;
-
-  /* nothing to do */
-  if (!totlvl) {
-    return;
-  }
-
-  /* XXX - probably not necessary to regenerate the cddm so much? */
-
-  /* generate highest level with displacements */
-  cddm = CDDM_from_mesh(me);
-  DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
-  dispdm = multires_dm_create_local(
-      scene, ob, cddm, totlvl, totlvl, 0, 0, MULTIRES_IGNORE_SIMPLIFY);
-  cddm->release(cddm);
-
-  /* copy the new locations of the base verts into the mesh */
-  offset = dispdm->getNumVerts(dispdm) - me->totvert;
-  for (i = 0; i < me->totvert; i++) {
-    dispdm->getVertCo(dispdm, offset + i, me->mvert[i].co);
-  }
-
-  /* heuristic to produce a better-fitting base mesh */
-
-  cddm = CDDM_from_mesh(me);
-  pmap = cddm->getPolyMap(ob, cddm);
-  origco = MEM_calloc_arrayN(me->totvert, 3 * sizeof(float), "multires apply base origco");
-  for (i = 0; i < me->totvert; i++) {
-    copy_v3_v3(origco[i], me->mvert[i].co);
-  }
-
-  for (i = 0; i < me->totvert; i++) {
-    float avg_no[3] = {0, 0, 0}, center[3] = {0, 0, 0}, push[3];
-    float dist;
-    int tot = 0;
-
-    /* don't adjust verts not used by at least one poly */
-    if (!pmap[i].count) {
-      continue;
-    }
-
-    /* find center */
-    for (j = 0; j < pmap[i].count; j++) {
-      const MPoly *p = &me->mpoly[pmap[i].indices[j]];
-
-      /* this double counts, not sure if that's bad or good */
-      for (k = 0; k < p->totloop; k++) {
-        int vndx = me->mloop[p->loopstart + k].v;
-        if (vndx != i) {
-          add_v3_v3(center, origco[vndx]);
-          tot++;
-        }
-      }
-    }
-    mul_v3_fl(center, 1.0f / tot);
-
-    /* find normal */
-    for (j = 0; j < pmap[i].count; j++) {
-      const MPoly *p = &me->mpoly[pmap[i].indices[j]];
-      MPoly fake_poly;
-      MLoop *fake_loops;
-      float(*fake_co)[3];
-      float no[3];
-
-      /* set up poly, loops, and coords in order to call
-       * BKE_mesh_calc_poly_normal_coords() */
-      fake_poly.totloop = p->totloop;
-      fake_poly.loopstart = 0;
-      fake_loops = MEM_malloc_arrayN(p->totloop, sizeof(MLoop), "fake_loops");
-      fake_co = MEM_malloc_arrayN(p->totloop, 3 * sizeof(float), "fake_co");
-
-      for (k = 0; k < p->totloop; k++) {
-        int vndx = me->mloop[p->loopstart + k].v;
-
-        fake_loops[k].v = k;
-
-        if (vndx == i) {
-          copy_v3_v3(fake_co[k], center);
-        }
-        else {
-          copy_v3_v3(fake_co[k], origco[vndx]);
-        }
-      }
-
-      BKE_mesh_calc_poly_normal_coords(&fake_poly, fake_loops, (const float(*)[3])fake_co, no);
-      MEM_freeN(fake_loops);
-      MEM_freeN(fake_co);
-
-      add_v3_v3(avg_no, no);
-    }
-    normalize_v3(avg_no);
-
-    /* push vertex away from the plane */
-    dist = v3_dist_from_plane(me->mvert[i].co, center, avg_no);
-    copy_v3_v3(push, avg_no);
-    mul_v3_fl(push, dist);
-    add_v3_v3(me->mvert[i].co, push);
-  }
-
-  MEM_freeN(origco);
-  cddm->release(cddm);
-
-  /* Vertices were moved around, need to update normals after all the vertices are updated
-   * Probably this is possible to do in the loop above, but this is rather tricky because
-   * we don't know all needed vertices' coordinates there yet.
-   */
-  BKE_mesh_calc_normals(me);
-
-  /* subdivide the mesh to highest level without displacements */
-  cddm = CDDM_from_mesh(me);
-  DM_set_only_copy(cddm, &CD_MASK_BAREMESH);
-  origdm = subsurf_dm_create_local(scene,
-                                   ob,
-                                   cddm,
-                                   totlvl,
-                                   0,
-                                   0,
-                                   mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE,
-                                   0,
-      

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list