diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 52ff8ac03d5..2151f5929a9 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -27,14 +27,16 @@ #include "BLI_utildefines.h" #include "BKE_attribute.hh" -#include "BKE_mesh_legacy_derived_mesh.hh" #include "BKE_modifier.hh" #include "BKE_shrinkwrap.hh" +#include "BKE_subdiv.hh" #include "BKE_deform.hh" #include "BKE_editmesh.hh" #include "BKE_mesh.hh" /* for OMP limits. */ #include "BKE_mesh_wrapper.hh" +#include "BKE_subdiv.hh" +#include "BKE_subdiv_deform.hh" #include "BKE_subsurf.hh" #include "DEG_depsgraph_query.hh" @@ -1335,9 +1337,39 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) 0, calc->numVerts, &data, shrinkwrap_calc_nearest_surface_point_cb_ex, &settings); } +static blender::Array shrinkwrap_calc_subdivided_positions( + Mesh *mesh, const int subdivision_level) +{ + using namespace blender; + using namespace blender::bke; + + Array positions = mesh->vert_positions(); + + subdiv::Settings settings{}; + settings.is_simple = false; + settings.is_adaptive = false; + settings.level = subdivision_level; + settings.use_creases = true; + + /* Default subdivision surface modifier settings: + * - UV Smooth:Keep Corners. + * - BoundarySmooth: All. */ + settings.vtx_boundary_interpolation = subdiv::SUBDIV_VTX_BOUNDARY_EDGE_ONLY; + settings.fvar_linear_interpolation = + subdiv::SUBDIV_FVAR_LINEAR_INTERPOLATION_CORNERS_AND_JUNCTIONS; + + subdiv::Subdiv *subdiv = subdiv::update_from_mesh(nullptr, &settings, mesh); + if (subdiv) { + subdiv::deform_coarse_vertices(subdiv, mesh, positions); + subdiv::free(subdiv); + } + + return positions; +} + void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, const ModifierEvalContext *ctx, - Scene *scene, + Scene * /*scene*/, Object *ob, Mesh *mesh, const MDeformVert *dvert, @@ -1345,9 +1377,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, float (*vertexCos)[3], int numVerts) { - - DerivedMesh *ss_mesh = nullptr; ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData; + blender::Array subdivided_positions; /* remove loop dependencies on derived meshes (TODO should this be done elsewhere?) */ if (smd->target == ob) { @@ -1387,35 +1418,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, /* Using vertices positions/normals as if a subsurface was applied */ if (smd->subsurfLevels) { - SubsurfModifierData ssmd = {{nullptr}}; - ssmd.subdivType = ME_CC_SUBSURF; /* catmull clark */ - ssmd.levels = smd->subsurfLevels; /* levels */ - - /* TODO: to be moved to Mesh once we are done with changes in subsurf code. */ - DerivedMesh *dm = CDDM_from_mesh(mesh); - - ss_mesh = subsurf_make_derived_from_derived( - dm, - &ssmd, - scene, - nullptr, - (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : SubsurfFlags(0)); - - if (ss_mesh) { - calc.vert_positions = reinterpret_cast(ss_mesh->getVertArray(ss_mesh)); - if (calc.vert_positions) { - /* TRICKY: this code assumes subsurface will have the transformed original vertices - * in their original order at the end of the vert array. */ - calc.vert_positions = calc.vert_positions + ss_mesh->getNumVerts(ss_mesh) - - dm->getNumVerts(dm); - } - } - - /* Just to make sure we are not leaving any memory behind */ - BLI_assert(ssmd.emCache == nullptr); - BLI_assert(ssmd.mCache == nullptr); - - dm->release(dm); + subdivided_positions = shrinkwrap_calc_subdivided_positions(mesh, smd->subsurfLevels); + calc.vert_positions = reinterpret_cast(subdivided_positions.data()); } } @@ -1442,11 +1446,6 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, BKE_shrinkwrap_free_tree(&tree); } - - /* free memory */ - if (ss_mesh) { - ss_mesh->release(ss_mesh); - } } void shrinkwrapParams_deform(const ShrinkwrapParams ¶ms,