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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2013-01-24 08:02:30 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-01-24 08:02:30 +0400
commit296f91c4cc02a5822bf8c74031be1ec35db86d3c (patch)
tree12e179be54ba32ad6a51744c9d8ccc04fc151fd0 /source
parent5489d5c2b5cb984112fe1b8dc1dbabbfbd6fb473 (diff)
add 'deform - integrate' option to mesh-cache,
This means the deformation on the input to the modifier can be re-applied ontop of the mesh cache. In practice this is most useful for using corrective shape-keys with mesh-cache.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_mesh.h10
-rw-r--r--source/blender/blenkernel/intern/mesh.c62
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h7
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c13
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c58
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_util.h4
7 files changed, 156 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 3466a914bce..cfe562e231c 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -100,6 +100,16 @@ void BKE_mesh_calc_poly_center(struct MPoly *mpoly, struct MLoop *loopstart,
float BKE_mesh_calc_poly_area(struct MPoly *mpoly, struct MLoop *loopstart,
struct MVert *mvarray, const float polynormal[3]);
+void BKE_mesh_calc_relative_deform(
+ const struct MPoly *mpoly, const int totpoly,
+ const struct MLoop *mloop, const int totvert,
+
+ const float (*vert_cos_src)[3],
+ const float (*vert_cos_dst)[3],
+
+ const float (*vert_cos_org)[3],
+ float (*vert_cos_new)[3]);
+
/* Find the index of the loop in 'poly' which references vertex,
* returns -1 if not found */
int poly_find_loop_from_vert(const struct MPoly *poly,
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 79cbd2ef886..03df0c28944 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -2993,6 +2993,68 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
}
}
+/**
+ * This function takes the difference between 2 vertex-coord-arrays
+ * (\a vert_cos_src, \a vert_cos_dst),
+ * and applies the difference to \a vert_cos_new relative to \a vert_cos_org.
+ *
+ * \param vert_cos_src reference deform source.
+ * \param vert_cos_dst reference deform destination.
+ *
+ * \param vert_cos_org reference for the output location.
+ * \param vert_cos_new resulting coords.
+ */
+void BKE_mesh_calc_relative_deform(
+ const MPoly *mpoly, const int totpoly,
+ const MLoop *mloop, const int totvert,
+
+ const float (*vert_cos_src)[3],
+ const float (*vert_cos_dst)[3],
+
+ const float (*vert_cos_org)[3],
+ float (*vert_cos_new)[3])
+{
+ const MPoly *mp;
+ int i;
+
+ int *vert_accum = MEM_callocN(sizeof(*vert_accum) * totvert, __func__);
+
+ memset(vert_cos_new, '\0', sizeof(*vert_cos_new) * totvert);
+
+ for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
+ const MLoop *loopstart = mloop + mp->loopstart;
+ int j;
+
+ for (j = 0; j < mp->totloop; j++) {
+ int v_prev = (loopstart + ((mp->totloop + (j - 1)) % mp->totloop))->v;
+ int v_curr = (loopstart + j)->v;
+ int v_next = (loopstart + ((j + 1) % mp->totloop))->v;
+
+ float tvec[3];
+
+ barycentric_transform(
+ tvec, vert_cos_dst[v_curr],
+ vert_cos_org[v_prev], vert_cos_org[v_curr], vert_cos_org[v_next],
+ vert_cos_src[v_prev], vert_cos_src[v_curr], vert_cos_src[v_next]
+ );
+
+ add_v3_v3(vert_cos_new[v_curr], tvec);
+ vert_accum[v_curr] += 1;
+ }
+ }
+
+ for (i = 0; i < totvert; i++) {
+ if (vert_accum[i]) {
+ mul_v3_fl(vert_cos_new[i], 1.0f / (float)vert_accum[i]);
+ }
+ else {
+ copy_v3_v3(vert_cos_new[i], vert_cos_org[i]);
+ }
+ }
+
+ MEM_freeN(vert_accum);
+}
+
/* Find the index of the loop in 'poly' which references vertex,
* returns -1 if not found */
int poly_find_loop_from_vert(const MPoly *poly, const MLoop *loopstart,
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 42ddbd84368..117eac0e42b 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1175,6 +1175,8 @@ typedef struct MeshCacheModifierData {
char interp;
float factor;
+ char deform_mode;
+ char pad[7];
/* play_mode == MOD_MESHCACHE_PLAY_CFEA */
float frame_start;
@@ -1195,6 +1197,11 @@ enum {
};
enum {
+ MOD_MESHCACHE_DEFORM_OVERWRITE = 0,
+ MOD_MESHCACHE_DEFORM_INTEGRATE = 1
+};
+
+enum {
MOD_MESHCACHE_INTERP_NONE = 0,
MOD_MESHCACHE_INTERP_LINEAR = 1,
// MOD_MESHCACHE_INTERP_CARDINAL = 2
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index c427b9860e3..21ab11271c4 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -3489,6 +3489,14 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem prop_deform_mode_items[] = {
+ {MOD_MESHCACHE_DEFORM_OVERWRITE, "OVERWRITE", 0, "Overwrite",
+ "Replace vertex coords with cached values"},
+ {MOD_MESHCACHE_DEFORM_INTEGRATE, "INTEGRATE", 0, "Integrate",
+ "Integrate deformation from this modifiers input with the mesh-cache coords (useful for shape keys)"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem prop_interpolation_type_items[] = {
{MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None ", ""},
{MOD_MESHCACHE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
@@ -3553,6 +3561,11 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Time Mode", "");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "deform_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "deform_mode");
+ RNA_def_property_enum_items(prop, prop_deform_mode_items);
+ RNA_def_property_ui_text(prop, "Deform Mode", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_property_ui_text(prop, "File Path", "Path to external displacements file");
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index e74da2c5d2b..1dd41c349d9 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -28,6 +28,8 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
@@ -37,6 +39,7 @@
#include "BKE_DerivedMesh.h"
#include "BKE_scene.h"
#include "BKE_global.h"
+#include "BKE_mesh.h"
#include "BKE_main.h"
#include "MEM_guardedalloc.h"
@@ -84,6 +87,7 @@ static void copyData(ModifierData *md, ModifierData *target)
tmcmd->frame_scale = mcmd->frame_scale;
tmcmd->factor = mcmd->factor;
+ tmcmd->deform_mode = mcmd->deform_mode;
tmcmd->eval_frame = mcmd->eval_frame;
tmcmd->eval_time = mcmd->eval_time;
@@ -111,7 +115,8 @@ static void meshcache_do(
MeshCacheModifierData *mcmd, Object *ob, DerivedMesh *UNUSED(dm),
float (*vertexCos_Real)[3], int numVerts)
{
- float (*vertexCos_Store)[3] = (mcmd->factor < 1.0f) ?
+ const bool use_factor = mcmd->factor < 1.0f;
+ float (*vertexCos_Store)[3] = (use_factor || (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
MEM_mallocN(sizeof(*vertexCos_Store) * numVerts, __func__) : NULL;
float (*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real;
@@ -229,8 +234,57 @@ static void meshcache_do(
}
}
+ /* tricky shape key integration (slow!) */
+ if (mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE) {
+ /* we could support any object type */
+ if (ob->type != OB_MESH) {
+ modifier_setError(&mcmd->modifier, "'Integrate' only valid for Mesh objects");
+ }
+ else {
+ Mesh *me = ob->data;
+ if (me->totvert != numVerts) {
+ modifier_setError(&mcmd->modifier, "'Integrate' original mesh vertex mismatch");
+ }
+ else {
+ if (me->totpoly == 0) {
+ modifier_setError(&mcmd->modifier, "'Integrate' requires faces");
+ }
+ else {
+ /* the moons align! */
+ int i;
+
+ float (*vertexCos_Source)[3] = MEM_mallocN(sizeof(*vertexCos_Source) * numVerts, __func__);
+ float (*vertexCos_New)[3] = MEM_mallocN(sizeof(*vertexCos_New) * numVerts, __func__);
+ MVert *mv = me->mvert;
+
+ for (i = 0; i < numVerts; i++, mv++) {
+ copy_v3_v3(vertexCos_Source[i], mv->co);
+ }
+
+ BKE_mesh_calc_relative_deform(
+ me->mpoly, me->totpoly,
+ me->mloop, me->totvert,
+
+ (const float (*)[3])vertexCos_Source, /* from the original Mesh*/
+ (const float (*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */
+
+ (const float (*)[3])vertexCos, /* the result of this modifier */
+ vertexCos_New /* the result of this function */
+ );
+
+ /* write the corrected locations back into the result */
+ memcpy(use_factor ? vertexCos : vertexCos_Real, vertexCos_New, sizeof(*vertexCos) * numVerts);
+
+ MEM_freeN(vertexCos_Source);
+ MEM_freeN(vertexCos_New);
+ }
+ }
+ }
+ }
+
if (vertexCos_Store) {
- if (ok) {
+
+ if (ok && use_factor) {
interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.c b/source/blender/modifiers/intern/MOD_meshcache_util.c
index 9068eb87581..679a79322c3 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_util.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.c
@@ -23,8 +23,12 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
+#include "MEM_guardedalloc.h"
+
#include "MOD_meshcache_util.h"
void MOD_meshcache_calc_range(const float frame, const char interp,
diff --git a/source/blender/modifiers/intern/MOD_meshcache_util.h b/source/blender/modifiers/intern/MOD_meshcache_util.h
index 4cbae43d051..d7e71518f77 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_util.h
+++ b/source/blender/modifiers/intern/MOD_meshcache_util.h
@@ -26,6 +26,9 @@
#ifndef __MOD_MESHCACHE_UTIL_H__
+struct MPoly;
+struct MLoop;
+
/* MOD_meshcache_mdd.c */
bool MOD_meshcache_read_mdd_index(FILE *fp,
float (*vertexCos)[3], const int vertex_tot,
@@ -54,6 +57,7 @@ bool MOD_meshcache_read_pc2_times(const char *filepath,
const float time, const float fps, const char time_mode,
const char **err_str);
+/* MOD_meshcache_util.c */
void MOD_meshcache_calc_range(const float frame, const char interp,
const int frame_tot,
int r_index_range[2], float *r_factor);