Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/editors/object/CMakeLists.txt1
-rw-r--r--source/blender/editors/object/object_modifier.c26
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/modifiers/CMakeLists.txt1
-rw-r--r--source/blender/modifiers/MOD_modifier_helpers.h39
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c92
6 files changed, 126 insertions, 35 deletions
diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt
index e25b04668bc..305e3287029 100644
--- a/source/blender/editors/object/CMakeLists.txt
+++ b/source/blender/editors/object/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
../../imbuf
../../makesdna
../../makesrna
+ ../../modifiers
../../python
../../render/extern/include
../../windowmanager
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index dd04a730542..2e922e7f963 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -90,6 +90,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "MOD_modifier_helpers.h"
+
#include "object_intern.h"
static void modifier_skin_customdata_delete(struct Object *ob);
@@ -2331,17 +2333,41 @@ static int surfacedeform_bind_poll(bContext *C)
static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform);
if (!smd)
return OPERATOR_CANCELLED;
if (smd->flags & MOD_SDEF_BIND) {
+ /* Un-binding happens inside the modifier when it's evaluated. */
smd->flags &= ~MOD_SDEF_BIND;
}
else if (smd->target) {
+ DerivedMesh *dm;
+ int mode = smd->modifier.mode;
+
+ /* Force modifier to run, it will call binding routine. */
+ smd->modifier.mode |= eModifierMode_Realtime;
smd->flags |= MOD_SDEF_BIND;
+
+ if (ob->type == OB_MESH) {
+ dm = mesh_create_derived_view(depsgraph, scene, ob, 0);
+ dm->release(dm);
+ }
+ else if (ob->type == OB_LATTICE) {
+ BKE_lattice_modifiers_calc(depsgraph, scene, ob);
+ }
+ else if (ob->type == OB_MBALL) {
+ BKE_displist_make_mball(depsgraph, scene, ob);
+ }
+ else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
+ BKE_displist_make_curveTypes(depsgraph, scene, ob, 0);
+ }
+
+ smd->modifier.mode = mode;
}
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 148ffed7c7f..31900b98564 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1624,7 +1624,9 @@ typedef struct SurfaceDeformModifierData {
/* Surface Deform modifier flags */
enum {
+ /* This indicates "do bind on next modifier evaluation" as well as "is bound". */
MOD_SDEF_BIND = (1 << 0),
+
MOD_SDEF_USES_LOOPTRI = (1 << 1),
MOD_SDEF_HAS_CONCAVE = (1 << 2),
};
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 397a3263e22..3707819f1fe 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -106,6 +106,7 @@ set(SRC
intern/MOD_weightvgproximity.c
intern/MOD_wireframe.c
+ MOD_modifier_helpers
MOD_modifiertypes.h
intern/MOD_fluidsim_util.h
intern/MOD_meshcache_util.h
diff --git a/source/blender/modifiers/MOD_modifier_helpers.h b/source/blender/modifiers/MOD_modifier_helpers.h
new file mode 100644
index 00000000000..0356bf74d43
--- /dev/null
+++ b/source/blender/modifiers/MOD_modifier_helpers.h
@@ -0,0 +1,39 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file MOD_modifier_helpers.h
+ * \ingroup modifiers
+ *
+ * Modifier-specific functions that should be accessible from outside the modifiers module.
+ */
+
+#ifndef __MOD_MODIFIER_HELPERS_H__
+#define __MOD_MODIFIER_HELPERS_H__
+
+struct Object;
+struct SurfaceDeformModifierData;
+
+/* Defined in MOD_surfacedeform.c */
+bool MOD_surfacedeform_bind(struct Object *ob, struct SurfaceDeformModifierData *smd);
+
+
+#endif /* __MOD_MODIFIER_HELPERS_H__ */
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index ae011986c47..ea12d8995b6 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -1,3 +1,5 @@
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -6,15 +8,19 @@
#include "BLI_math_geom.h"
#include "BLI_task.h"
-#include "BKE_cdderivedmesh.h"
+#include "BKE_bvhutils.h"
+#include "BKE_mesh.h"
#include "BKE_editmesh.h"
+#include "BKE_library.h"
#include "BKE_library_query.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "DEG_depsgraph.h"
#include "MEM_guardedalloc.h"
+#include "MOD_modifier_helpers.h"
#include "MOD_util.h"
typedef struct SDefAdjacency {
@@ -905,14 +911,14 @@ static void bindVert(
}
static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)[3],
- unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, DerivedMesh *tdm)
+ unsigned int numverts, unsigned int tnumpoly, unsigned int tnumverts, Mesh *target)
{
BVHTreeFromMesh treeData = {NULL};
- const MVert *mvert = tdm->getVertArray(tdm);
- const MPoly *mpoly = tdm->getPolyArray(tdm);
- const MEdge *medge = tdm->getEdgeArray(tdm);
- const MLoop *mloop = tdm->getLoopArray(tdm);
- unsigned int tnumedges = tdm->getNumEdges(tdm);
+ const MVert *mvert = target->mvert;
+ const MPoly *mpoly = target->mpoly;
+ const MEdge *medge = target->medge;
+ const MLoop *mloop = target->mloop;
+ unsigned int tnumedges = target->totedge;
int adj_result;
SDefAdjacencyArray *vert_edges;
SDefAdjacency *adj_array;
@@ -946,7 +952,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)
return false;
}
- bvhtree_from_mesh_get(&treeData, tdm, BVHTREE_FROM_LOOPTRI, 2);
+ BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2);
if (treeData.tree == NULL) {
modifier_setError((ModifierData *)smd, "Out of memory");
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
@@ -975,7 +981,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)
.mpoly = mpoly,
.medge = medge,
.mloop = mloop,
- .looptri = tdm->getLoopTriArray(tdm),
+ .looptri = BKE_mesh_runtime_looptri_ensure(target),
.targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetBindVertArray"),
.bind_verts = smd->verts,
.vertexCos = vertexCos,
@@ -1035,6 +1041,30 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd, float (*vertexCos)
return data.success == 1;
}
+static Mesh *surfacedeform_get_mesh(SurfaceDeformModifierData *smd, bool *r_needsfree)
+{
+ Mesh *mesh;
+
+ /* Handle target mesh both in and out of edit mode */
+ if (smd->target->mode & OB_MODE_EDIT) {
+ BMEditMesh *em = BKE_editmesh_from_object(smd->target);
+ mesh = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0});
+ *r_needsfree = true;
+ }
+ else {
+ mesh = get_mesh_eval_for_modifier(smd->target,
+ smd->modifier.mode & eModifierMode_Render ? MOD_APPLY_RENDER : 0);
+ *r_needsfree = false;
+ }
+
+ if (!mesh) {
+ mesh = get_mesh(smd->target, NULL, NULL, NULL, false, false);
+ *r_needsfree = true;
+ }
+
+ return mesh;
+}
+
static void deformVert(
void *__restrict userdata,
const int index,
@@ -1097,7 +1127,8 @@ static void surfacedeformModifier_do(
float (*vertexCos)[3], unsigned int numverts, Object *ob)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- DerivedMesh *tdm;
+ bool free_target;
+ Mesh *target;
unsigned int tnumverts, tnumpoly;
/* Exit function if bind flag is not set (free bind data if any) */
@@ -1106,22 +1137,14 @@ static void surfacedeformModifier_do(
return;
}
- /* Handle target mesh both in and out of edit mode */
- if (smd->target->mode & OB_MODE_EDIT) {
- BMEditMesh *em = BKE_editmesh_from_object(smd->target);
- tdm = em->derivedFinal;
- }
- else {
- tdm = smd->target->derivedFinal;
- }
-
- if (!tdm) {
+ target = surfacedeform_get_mesh(smd, &free_target);
+ if (!target) {
modifier_setError(md, "No valid target mesh");
return;
}
- tnumverts = tdm->getNumVerts(tdm);
- tnumpoly = tdm->getNumPolys(tdm);
+ tnumverts = target->totvert;
+ tnumpoly = target->totpoly;
/* If not bound, execute bind */
if (!(smd->verts)) {
@@ -1130,7 +1153,7 @@ static void surfacedeformModifier_do(
invert_m4_m4(tmp_mat, ob->obmat);
mul_m4_m4m4(smd->mat, tmp_mat, smd->target->obmat);
- if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, tdm)) {
+ if (!surfacedeformBind(smd, vertexCos, numverts, tnumpoly, tnumverts, target)) {
smd->flags &= ~MOD_SDEF_BIND;
return;
}
@@ -1139,10 +1162,12 @@ static void surfacedeformModifier_do(
/* Poly count checks */
if (smd->numverts != numverts) {
modifier_setError(md, "Verts changed from %u to %u", smd->numverts, numverts);
+ if (free_target) BKE_id_free(NULL, target);
return;
}
else if (smd->numpoly != tnumpoly) {
modifier_setError(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
+ if (free_target) BKE_id_free(NULL, target);
return;
}
@@ -1154,8 +1179,7 @@ static void surfacedeformModifier_do(
};
if (data.targetCos != NULL) {
- bool tdm_vert_alloc;
- const MVert * const mvert = DM_get_vert_array(tdm, &tdm_vert_alloc);
+ const MVert * const mvert = target->mvert;
for (int i = 0; i < tnumverts; i++) {
mul_v3_m4v3(data.targetCos[i], smd->mat, mvert[i].co);
@@ -1169,17 +1193,15 @@ static void surfacedeformModifier_do(
deformVert,
&settings);
- if (tdm_vert_alloc) {
- MEM_freeN((void *)mvert);
- }
-
MEM_freeN(data.targetCos);
}
+
+ if (free_target) BKE_id_free(NULL, target);
}
static void deformVerts(
ModifierData *md, const ModifierEvalContext *ctx,
- DerivedMesh *UNUSED(derivedData),
+ Mesh *UNUSED(mesh),
float (*vertexCos)[3], int numVerts)
{
surfacedeformModifier_do(md, vertexCos, numVerts, ctx->object);
@@ -1188,7 +1210,7 @@ static void deformVerts(
static void deformVertsEM(
ModifierData *md, const ModifierEvalContext *ctx,
struct BMEditMesh *UNUSED(editData),
- DerivedMesh *UNUSED(derivedData),
+ Mesh *UNUSED(mesh),
float (*vertexCos)[3], int numVerts)
{
surfacedeformModifier_do(md, vertexCos, numVerts, ctx->object);
@@ -1211,16 +1233,16 @@ ModifierTypeInfo modifierType_SurfaceDeform = {
/* copyData */ copyData,
- /* deformVerts_DM */ deformVerts,
+ /* deformVerts_DM */ NULL,
/* deformMatrices_DM */ NULL,
- /* deformVertsEM_DM */ deformVertsEM,
+ /* deformVertsEM_DM */ NULL,
/* deformMatricesEM_DM*/NULL,
/* applyModifier_DM */ NULL,
/* applyModifierEM_DM */NULL,
- /* deformVerts */ NULL,
+ /* deformVerts */ deformVerts,
/* deformMatrices */ NULL,
- /* deformVertsEM */ NULL,
+ /* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ NULL,
/* applyModifier */ NULL,
/* applyModifierEM */ NULL,