1
1

Compare commits

...

66 Commits

Author SHA1 Message Date
be4cdf572a Use BKE_mesh_apply_vert_coords instead of local defined version 2018-05-16 03:51:14 -04:00
03b0565a08 Fixed mesh_calc_modifier()
This makes generating modifiers work as well.
2018-05-15 18:30:31 +02:00
36d223a8f0 Changes from review 2018-05-12 01:12:18 -04:00
cb7d6a1764 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-11 06:19:28 -04:00
b11beff03d No more DerivedMesh in mesh_calc_modifiers
Also a little cleanup.
2018-05-11 04:39:05 -04:00
c73c5b686f Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-10 02:17:54 -04:00
fa6f45fc55 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-07 21:59:56 -04:00
f8aa1c0fd7 First pass at porting mesh_calc_modifiers from DerivedMesh to Mesh
DerivedMesh is almost completely removed from the main loop.

Added `_dep` to dm pointers to make usage of them easy to locate by
searching for `dm_dep`.

Still some work to do. It looks like some of these code paths aren't
entered into, maybe things could be simplified if we can be sure of
whats actually needed.
2018-05-03 05:21:58 -04:00
1448aa4585 Port various util functions from DerivedMesh to Mesh
Adds the following functions which are duplicates of
their `DerivedMesh` counterparts:
- `apply_vert_coords`
- `mesh_set_only_copy`
- `create_orco_mesh`
- `add_orco_mesh`
- `calc_weightpaint_vert_array_mesh`
- `mesh_update_weight_mcol`
- `mesh_init_origspace`
2018-05-03 05:17:28 -04:00
22f6f491e6 Add BKE_mesh_is_valid 2018-05-03 04:55:14 -04:00
0c500326c7 Add modifier_deformVerts_ensure_normals
Same as modwrap_deformVerts but for Mesh
2018-05-03 04:55:22 -04:00
76ba615f5c Add modifier_deformVerts_ensure_normals
Same as modwrap_deformVerts but for Mesh
2018-05-03 04:55:14 -04:00
229190c0be Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-02 02:24:49 -04:00
c8a3af8f5d Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-01 18:01:03 +02:00
92a0874378 Formatting 2018-05-01 16:43:22 +02:00
9bd7bd9f65 Use proper way to get CoW original 2018-05-01 16:43:11 +02:00
93ce0a7c48 Mesh *to_use → mesh_src 2018-05-01 14:55:19 +02:00
788b09b14a FIXUP for ModifierEvalContext introduction 2018-05-01 14:51:50 +02:00
4819cc4b41 Quiet unused var warning 2018-05-01 14:51:06 +02:00
6aebbdce37 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-01 14:40:36 +02:00
9bfe5d14e5 Extract common modifier parameters into ModifierEvalContext struct
The contents of the ModifierEvalContext struct are constant while iterating
over the modifier stack. The struct thus should be only created once,
outside any loop over the modifiers.
2018-05-01 14:39:32 +02:00
cb9efbb940 Reintroduce edgehash2 2018-05-01 11:49:16 +02:00
905b9c0f1d Reverted some changes to MOD_build 2018-05-01 11:32:11 +02:00
fa8f3dee46 Moved to other file, updated comment 2018-05-01 11:03:17 +02:00
b106caef82 Removing commented-out code 2018-05-01 11:03:09 +02:00
b35b8b6a65 Formatting 2018-05-01 11:02:58 +02:00
8910990fd4 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-05-01 10:45:00 +02:00
8ee815b1e2 Removed TODO 2018-04-26 17:22:18 +02:00
091b2430bd Moved vertex merging to mesh_merge.c 2018-04-26 17:19:13 +02:00
1d041aa677 Handled most of Cambpell's review comments 2018-04-26 17:05:14 +02:00
4ef7832192 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-04-25 16:56:48 +02:00
0c4b2cddf8 Ported Array modifier 2018-04-25 16:56:38 +02:00
3c2935c2f3 Introduced CDDM_from_mesh_ex() to create a non-referencing CDDM
This allows the mesh to be freed and the CDDM kept.
2018-04-25 15:38:38 +02:00
6b0911b814 Vertex merging in mirror modifier is working
Also fixed some memory issues.
2018-04-25 15:30:57 +02:00
7b94c959ca Almost finished mirror modifier (still needs vertex merging) 2018-04-25 14:29:08 +02:00
3b967b273c Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-04-25 12:41:07 +02:00
59f831ce7b Almost ported mirror modifier 2018-04-25 12:21:07 +02:00
7142ae5b29 Typo fix 2018-04-25 12:09:12 +02:00
597dbc38dd Ported armature modifier
The mesh parameter of armature_deform_verts() is now const, to indicate
that it's safe to pass ob->data to it directly.
2018-04-25 11:45:18 +02:00
353900fcd5 Start porting Armature modifier 2018-04-25 11:45:18 +02:00
529f865588 Consistent naming 2018-04-25 11:45:18 +02:00
33afd0097b Removed commented-out code 2018-04-25 11:45:18 +02:00
7595cd468f Fixed memory leak 2018-04-25 11:45:18 +02:00
210c27eed3 Use 'struct' keyword
Without this, the forward declaration is useless as the real declaration
needs to be known by the compiler.
2018-04-25 11:45:18 +02:00
f853cd86e9 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-04-25 10:18:05 +02:00
db45a165f9 Removed potential free of NULL 2018-04-25 10:14:46 +02:00
6f16ce5df9 Just pass mesh=NULL to wrapped modifier when dm=NULL 2018-04-25 10:08:21 +02:00
6e09972848 Added note about potential crash in add_orco_dm() 2018-04-25 09:53:32 +02:00
cdea65ff96 Construct new Mesh instead of writing to ob->data
Even when ob->data is a CoW copy, it can still be used by different objects
and thus shouldn't be modified by a modifier.
2018-04-25 09:47:34 +02:00
116b1b9e4f Removed unnecessary free 2018-04-24 12:07:03 +02:00
5180703926 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-04-24 11:52:57 +02:00
844a6d1820 Copy CDDM to allow freeing the mesh 2018-04-24 11:51:13 +02:00
848061ce82 Don't use MEM_SAFE_FREE as it causes warnings 2018-04-24 11:51:13 +02:00
53d4f5c758 Remove debug stuff 2018-04-24 11:51:13 +02:00
dfa123916f Always get the vertex coordinates from the original mesh
Get from original instead of CoW copy, otherwise there is the risk of
deforming already-deformed coordinates.
2018-04-24 11:51:13 +02:00
baca92ce0a Some debugging going on here 2018-04-24 11:51:13 +02:00
5a6af777a8 Precious attempt at being ok 2018-04-24 11:51:13 +02:00
fffd452231 Ported Build modifier to use Mesh instead of DerivedMesh. 2018-04-24 11:51:13 +02:00
7d697cdfef Fix crash when no mesh in passed to deform functions 2018-04-24 04:24:29 -04:00
2146f74f22 Merge remote-tracking branch 'origin/blender2.8' into temp-modifier-rm-cddm 2018-04-20 10:21:35 +02:00
ecbe08f036 remove debug prints and stuff 2018-04-20 10:10:03 +02:00
23509c6ca5 Mesh deformation seems to be working 2018-04-19 17:20:25 +02:00
c7c76bd2a3 Introdicing EditMeshData 2018-04-19 12:46:58 +02:00
cb9fe2b39b Operate on CoW mesh directly, only use DM when not NULL 2018-04-19 12:46:19 +02:00
6e56d94913 Modifiers: simple deform modifier object mode, DerivedMesh → Mesh 2018-04-19 11:32:41 +02:00
fe960a1954 Modifiers: Add wrapper functions with Mesh / DerivedMesh conversion
Makes the follow changes:

- Add new `deform*` and `apply*` function pointers to `ModifierTypeInfo` that take `Mesh`, and rename the old functions to indicate that they take `DerivedMesh`. These new functions are currently set to `NULL` for all modifiers.
- Add wrapper `modifier_deform*` and `modifier_apply*` functions in two variants: one that works with `Mesh` and the other which works with `DerivedMesh` that is named with `*_DM_depercated`. These functions check which type of data the modifier supports and converts if necessary
- Update the rest of Blender to be aware and make use of these new functions

The goal of these changes is to make it possible to port to using `Mesh` incrementally without ever needing to enter into a state where modifiers don't work. After everything has been ported over the old functions and wrappers could be removed.

Reviewers: campbellbarton, sergey, mont29

Subscribers: sybren

Tags: #bf_blender_2.8

Differential Revision: https://developer.blender.org/D3155
2018-04-18 15:45:54 +02:00
5 changed files with 555 additions and 127 deletions

View File

@@ -458,6 +458,7 @@ void BKE_mesh_calc_relative_deform(
/* *** mesh_validate.c *** */
int BKE_mesh_validate(struct Mesh *me, const int do_verbose, const int cddata_check_mask);
bool BKE_mesh_is_valid(struct Mesh *me);
int BKE_mesh_validate_material_indices(struct Mesh *me);
bool BKE_mesh_validate_arrays(

View File

@@ -498,6 +498,10 @@ void modifier_deformVerts(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct Mesh *mesh, float (*vertexCos)[3], int numVerts);
void modifier_deformVerts_ensure_normals(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct Mesh *mesh, float (*vertexCos)[3], int numVerts);
void modifier_deformMatrices(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct Mesh *mesh, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
@@ -516,6 +520,10 @@ struct Mesh *modifier_applyModifier(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct Mesh *mesh);
struct Mesh *modifier_applyModifier_ensure_normals(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct Mesh *mesh);
struct Mesh *modifier_applyModifierEM(
struct ModifierData *md, const struct ModifierEvalContext *ctx,
struct BMEditMesh *editData, struct Mesh *mesh);

View File

@@ -84,8 +84,10 @@
#ifdef USE_MODIFIER_VALIDATE
# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true)))
# define ASSERT_IS_VALID_MESH(mesh) (BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
#else
# define ASSERT_IS_VALID_DM(dm)
# define ASSERT_IS_VALID_MESH(mesh)
#endif
@@ -95,6 +97,8 @@ static ThreadRWMutex loops_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
static void mesh_init_origspace(Mesh *mesh);
/* -------------------------------------------------------------------- */
@@ -891,6 +895,20 @@ void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask)
#endif
}
void mesh_set_only_copy(Mesh *mesh, CustomDataMask mask)
{
CustomData_set_only_copy(&mesh->vdata, mask);
CustomData_set_only_copy(&mesh->edata, mask);
CustomData_set_only_copy(&mesh->fdata, mask);
/* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with
* weight paint mode when there are modifiers applied, needs further investigation,
* see replies to r50969, Campbell */
#if 0
CustomData_set_only_copy(&mesh->ldata, mask);
CustomData_set_only_copy(&mesh->pdata, mask);
#endif
}
void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
{
CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData);
@@ -1265,6 +1283,30 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int lay
return dm;
}
static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
{
Mesh *mesh;
float (*orco)[3];
int free;
if (em) {
mesh = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0});
}
else {
BKE_id_copy_ex(NULL, &me->id, (ID**)&mesh,
LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false);
}
orco = get_orco_coords_dm(ob, em, layer, &free);
if (orco) {
BKE_mesh_apply_vert_coords(mesh, orco);
if (free) MEM_freeN(orco);
}
return mesh;
}
static void add_orco_dm(
Object *ob, BMEditMesh *em, DerivedMesh *dm,
DerivedMesh *orcodm, int layer)
@@ -1303,6 +1345,48 @@ static void add_orco_dm(
}
}
static void add_orco_mesh(
Object *ob, BMEditMesh *em, Mesh *mesh,
Mesh *orco_mesh, int layer)
{
float (*orco)[3], (*layerorco)[3];
int totvert, free;
totvert = mesh->totvert;
if (orco_mesh) {
free = 1;
if (orco_mesh->totvert == totvert) {
orco = BKE_mesh_vertexCos_get(orco_mesh, NULL);
}
else {
orco = BKE_mesh_vertexCos_get(mesh, NULL);
}
}
else {
/* TODO(sybren): totvert should potentially change here, as ob->data
* or em may have a different number of vertices than dm. */
orco = get_orco_coords_dm(ob, em, layer, &free);
}
if (orco) {
if (layer == CD_ORCO) {
BKE_mesh_orco_verts_transform(ob->data, orco, totvert, 0);
}
if (!(layerorco = CustomData_get_layer(&mesh->vdata, layer))) {
CustomData_add_layer(&mesh->vdata, layer, CD_CALLOC, NULL, mesh->totvert);
BKE_mesh_update_customdata_pointers(mesh, false);
layerorco = CustomData_get_layer(&mesh->vdata, layer);
}
memcpy(layerorco, orco, sizeof(float) * 3 * totvert);
if (free) MEM_freeN(orco);
}
}
/* weight paint colors */
/* Something of a hack, at the moment deal with weightpaint
@@ -1528,6 +1612,81 @@ static void calc_weightpaint_vert_array(
}
}
static void calc_weightpaint_vert_array_mesh(
Object *ob, Mesh *mesh, int const draw_flag, DMWeightColorInfo *dm_wcinfo,
unsigned char (*r_wtcol_v)[4])
{
BMEditMesh *em = BKE_editmesh_from_object(ob);
const int numVerts = mesh->totvert;
if ((ob->actdef != 0) &&
(CustomData_has_layer(em ? &em->bm->vdata : &mesh->vdata, CD_MDEFORMVERT)))
{
unsigned char (*wc)[4] = r_wtcol_v;
unsigned int i;
/* variables for multipaint */
const int defbase_tot = BLI_listbase_count(&ob->defbase);
const int defbase_act = ob->actdef - 1;
int defbase_sel_tot = 0;
bool *defbase_sel = NULL;
if (draw_flag & CALC_WP_MULTIPAINT) {
defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_sel_tot);
if (defbase_sel_tot > 1 && (draw_flag & CALC_WP_MIRROR_X)) {
BKE_object_defgroup_mirror_selection(ob, defbase_tot, defbase_sel, defbase_sel, &defbase_sel_tot);
}
}
/* editmesh won't have deform verts unless modifiers require it,
* avoid having to create an array of deform-verts only for drawing
* by reading from the bmesh directly. */
if (em) {
BMIter iter;
BMVert *eve;
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
BLI_assert(cd_dvert_offset != -1);
BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
const MDeformVert *dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
calc_weightpaint_vert_color(
(unsigned char *)wc, dv, dm_wcinfo,
defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
wc++;
}
}
else {
const MDeformVert *dv = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
for (i = numVerts; i != 0; i--, wc++, dv++) {
calc_weightpaint_vert_color(
(unsigned char *)wc, dv, dm_wcinfo,
defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
}
}
if (defbase_sel) {
MEM_freeN(defbase_sel);
}
}
else {
unsigned char col[4];
if ((ob->actdef == 0) && !BLI_listbase_is_empty(&ob->defbase)) {
/* color-code for missing data (full brightness isn't easy on the eye). */
ARRAY_SET_ITEMS(col, 0xa0, 0, 0xa0, 0xff);
}
else if (draw_flag & (CALC_WP_GROUP_USER_ACTIVE | CALC_WP_GROUP_USER_ALL)) {
copy_v3_v3_char((char *)col, dm_wcinfo->alert_color);
col[3] = 255;
}
else {
weightpaint_color(col, dm_wcinfo, 0.0f);
}
copy_vn_i((int *)r_wtcol_v, numVerts, *((int *)col));
}
}
/** return an array of vertex weight colors from given weights, caller must free.
*
* \note that we could save some memory and allocate RGB only but then we'd need to
@@ -1620,6 +1779,80 @@ void DM_update_weight_mcol(
}
}
void mesh_update_weight_mcol(
Object *ob, Mesh *mesh, int const draw_flag,
float *weights, int num, const int *indices)
{
BMEditMesh *em = BKE_editmesh_from_object(ob);
unsigned char (*wtcol_v)[4];
int numVerts = mesh->totvert;
int i;
if (em) {
BKE_editmesh_color_ensure(em, BM_VERT);
wtcol_v = em->derivedVertColor;
}
else {
wtcol_v = MEM_malloc_arrayN(numVerts, sizeof(*wtcol_v), __func__);
}
/* Weights are given by caller. */
if (weights) {
float *w = weights;
/* If indices is not NULL, it means we do not have weights for all vertices,
* so we must create them (and set them to zero)... */
if (indices) {
w = MEM_calloc_arrayN(numVerts, sizeof(float), "Temp weight array DM_update_weight_mcol");
i = num;
while (i--)
w[indices[i]] = weights[i];
}
/* Convert float weights to colors. */
calc_colors_from_weights_array(numVerts, w, wtcol_v);
if (indices)
MEM_freeN(w);
}
else {
/* No weights given, take them from active vgroup(s). */
calc_weightpaint_vert_array_mesh(ob, mesh, draw_flag, &G_dm_wcinfo, wtcol_v);
}
if (em) {
/* editmesh draw function checks specifically for this */
}
else {
const int totpoly = mesh->totpoly;
const int totloop = mesh->totloop;
unsigned char(*wtcol_l)[4] = CustomData_get_layer(&mesh->ldata, CD_PREVIEW_MLOOPCOL);
MLoop *mloop = mesh->mloop, *ml;
MPoly *mp = mesh->mpoly;
int l_index;
int j;
/* now add to loops, so the data can be passed through the modifier stack
* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */
if (!wtcol_l) {
wtcol_l = MEM_malloc_arrayN(totloop, sizeof(*wtcol_l), __func__);
CustomData_add_layer(&mesh->ldata, CD_PREVIEW_MLOOPCOL, CD_ASSIGN, wtcol_l, totloop);
}
l_index = 0;
for (i = 0; i < totpoly; i++, mp++) {
ml = mloop + mp->loopstart;
for (j = 0; j < mp->totloop; j++, ml++, l_index++) {
copy_v4_v4_uchar(&wtcol_l[l_index][0],
&wtcol_v[ml->v][0]);
}
}
MEM_freeN(wtcol_v);
//dm->dirty |= DM_DIRTY_TESS_CDLAYERS; // XXX: Does Mesh need this?
}
}
static void DM_update_statvis_color(const Scene *scene, Object *ob, DerivedMesh *dm)
{
BMEditMesh *em = BKE_editmesh_from_object(ob);
@@ -1742,6 +1975,32 @@ static void dm_ensure_display_normals(DerivedMesh *dm)
}
}
static void mesh_ensure_display_normals(Mesh *mesh)
{
/* Note: mesh *may* have a poly CD_NORMAL layer (generated by a modifier needing poly normals e.g.).
* We do not use it here, though. And it should be tagged as temp!
*/
/* BLI_assert((CustomData_has_layer(&mesh->pdata, CD_NORMAL) == false)); */
if(mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL || !CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
float (*face_nors)[3] = NULL;
face_nors = MEM_malloc_arrayN(mesh->totpoly, sizeof(*face_nors), "face_nors");
/* if normals are dirty we want to calculate vertex normals too */
bool only_face_normals = !(mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL);
/* calculate face normals */
BKE_mesh_calc_normals_poly(
mesh->mvert, NULL, mesh->totvert, mesh->mloop, mesh->mpoly,
mesh->totloop, mesh->totpoly, face_nors,
only_face_normals);
CustomData_add_layer(&mesh->pdata, CD_NORMAL, CD_ASSIGN, face_nors, mesh->totpoly);
mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
}
}
static void mesh_calc_modifiers(
struct Depsgraph *depsgraph, Scene *scene, Object *ob, float (*inputVertexCos)[3],
const bool useRenderParams, int useDeform,
@@ -1749,7 +2008,7 @@ static void mesh_calc_modifiers(
const int index, const bool useCache, const bool build_shapekey_layers,
const bool allow_gpu,
/* return args */
DerivedMesh **r_deform, DerivedMesh **r_final)
Mesh **r_deform_mesh, Mesh **r_final_mesh)
{
Mesh *me = ob->data;
/* Always get the vertex coordinates from the original mesh. Otherwise
@@ -1760,7 +2019,6 @@ static void mesh_calc_modifiers(
/* XXX Always copying POLYINDEX, else tessellated data are no more valid! */
CustomDataMask mask, nextmask, previewmask = 0, append_mask = CD_MASK_ORIGINDEX;
float (*deformedVerts)[3] = NULL;
DerivedMesh *dm = NULL, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
const int required_mode = useRenderParams ? eModifierMode_Render : eModifierMode_Realtime;
bool isPrevDeform = false;
@@ -1782,7 +2040,6 @@ static void mesh_calc_modifiers(
const bool do_mod_wmcol = do_init_wmcol;
const bool do_loop_normals = (me->flag & ME_AUTOSMOOTH) != 0;
const float loop_normals_split_angle = me->smoothresh;
VirtualModifierData virtualModifierData;
@@ -1825,10 +2082,10 @@ static void mesh_calc_modifiers(
datamasks = modifiers_calcDataMasks(scene, ob, md, dataMask, required_mode, previewmd, previewmask);
curr = datamasks;
if (r_deform) {
*r_deform = NULL;
if (r_deform_mesh) {
*r_deform_mesh = NULL;
}
*r_final = NULL;
*r_final_mesh = NULL;
if (useDeform) {
if (inputVertexCos)
@@ -1852,7 +2109,7 @@ static void mesh_calc_modifiers(
if (!deformedVerts)
deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts);
modwrap_deformVerts(md, &mectx_deform, NULL, deformedVerts, numVerts);
modifier_deformVerts_ensure_normals(md, &mectx_deform, NULL, deformedVerts, numVerts);
}
else {
break;
@@ -1867,14 +2124,17 @@ static void mesh_calc_modifiers(
* places that wish to use the original mesh but with deformed
* coordinates (vpaint, etc.)
*/
if (r_deform) {
*r_deform = CDDM_from_mesh(me);
if (r_deform_mesh) {
BKE_id_copy_ex(NULL, &me->id, (ID**)r_deform_mesh,
LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false);
if (build_shapekey_layers)
add_shapekey_layers(dm, me, ob);
/* XXX: Is build_shapekey_layers ever even true? This should have crashed long ago... */
BLI_assert(!build_shapekey_layers);
//if (build_shapekey_layers)
// add_shapekey_layers(*r_deform_mesh, me, ob);
if (deformedVerts) {
CDDM_apply_vert_coords(*r_deform, deformedVerts);
BKE_mesh_apply_vert_coords(*r_deform_mesh, deformedVerts);
}
}
}
@@ -1890,9 +2150,9 @@ static void mesh_calc_modifiers(
/* Now apply all remaining modifiers. If useDeform is off then skip
* OnlyDeform ones.
*/
dm = NULL;
orcodm = NULL;
clothorcodm = NULL;
Mesh *mesh = NULL;
Mesh *orco_mesh = NULL;
Mesh *cloth_orco_mesh = NULL;
for (; md; md = md->next, curr = curr->next) {
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1907,7 +2167,7 @@ static void mesh_calc_modifiers(
continue;
}
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && mesh) {
modifier_setError(md, "Modifier requires original data, bad stack position");
continue;
}
@@ -1958,26 +2218,24 @@ static void mesh_calc_modifiers(
else
mask = 0;
if (dm && (mask & CD_MASK_ORCO))
add_orco_dm(ob, NULL, dm, orcodm, CD_ORCO);
if (mesh && (mask & CD_MASK_ORCO)) {
add_orco_mesh(ob, NULL, mesh, orco_mesh, CD_ORCO);
}
/* How to apply modifier depends on (a) what we already have as
* a result of previous modifiers (could be a DerivedMesh or just
* a result of previous modifiers (could be a Mesh or just
* deformed vertices) and (b) what type the modifier is.
*/
if (mti->type == eModifierTypeType_OnlyDeform) {
/* No existing verts to deform, need to build them. */
if (!deformedVerts) {
if (dm) {
/* Deforming a derived mesh, read the vertex locations
if (mesh) {
/* Deforming a mesh, read the vertex locations
* out of the mesh and deform them. Once done with this
* run of deformers verts will be written back.
*/
numVerts = dm->getNumVerts(dm);
deformedVerts =
MEM_malloc_arrayN(numVerts, sizeof(*deformedVerts), "dfmv");
dm->getVertCos(dm, deformedVerts);
deformedVerts = BKE_mesh_vertexCos_get(mesh, &numVerts);
}
else {
deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts);
@@ -1988,45 +2246,46 @@ static void mesh_calc_modifiers(
* to avoid giving bogus normals to the next modifier see: [#23673] */
if (isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
/* XXX, this covers bug #23673, but we may need normal calc for other types */
if (dm && dm->type == DM_TYPE_CDDM) {
CDDM_apply_vert_coords(dm, deformedVerts);
if (mesh) {
BKE_mesh_apply_vert_coords(mesh, deformedVerts);
}
}
modwrap_deformVerts(md, &mectx_deform, dm, deformedVerts, numVerts);
modifier_deformVerts_ensure_normals(md, &mectx_deform, mesh, deformedVerts, numVerts);
}
else {
DerivedMesh *ndm;
/* determine which data layers are needed by following modifiers */
if (curr->next)
nextmask = curr->next->mask;
else
nextmask = dataMask;
/* apply vertex coordinates or build a DerivedMesh as necessary */
if (dm) {
/* apply vertex coordinates or build a Mesh as necessary */
if (mesh) {
if (deformedVerts) {
/* XXX: What's the point of this copy?
DerivedMesh *tdm = CDDM_copy(dm);
dm->release(dm);
dm = tdm;
dm = tdm; */
CDDM_apply_vert_coords(dm, deformedVerts);
BKE_mesh_apply_vert_coords(mesh, deformedVerts);
}
}
else {
dm = CDDM_from_mesh(me);
ASSERT_IS_VALID_DM(dm);
BKE_id_copy_ex(NULL, &me->id, (ID**)&mesh,
LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false);
ASSERT_IS_VALID_MESH(mesh);
if (build_shapekey_layers)
add_shapekey_layers(dm, me, ob);
// XXX: port to Mesh if build_shapekey_layers can ever be true
//if (build_shapekey_layers)
// add_shapekey_layers(mesh, me, ob);
if (deformedVerts) {
CDDM_apply_vert_coords(dm, deformedVerts);
BKE_mesh_apply_vert_coords(mesh, deformedVerts);
}
if (do_init_wmcol)
DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL);
mesh_update_weight_mcol(ob, mesh, draw_flag, NULL, 0, NULL);
/* Constructive modifiers need to have an origindex
* otherwise they wont have anywhere to copy the data from.
@@ -2037,45 +2296,48 @@ static void mesh_calc_modifiers(
*/
if (need_mapping || (nextmask & CD_MASK_ORIGINDEX)) {
/* calc */
DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_poly_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totpoly);
/* Not worth parallelizing this, gives less than 0.1% overall speedup in best of best cases... */
range_vn_i(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0);
range_vn_i(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0);
range_vn_i(DM_get_poly_data_layer(dm, CD_ORIGINDEX), dm->numPolyData, 0);
range_vn_i(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX), mesh->totvert, 0);
range_vn_i(CustomData_get_layer(&mesh->edata, CD_ORIGINDEX), mesh->totedge, 0);
range_vn_i(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX), mesh->totpoly, 0);
}
}
/* set the DerivedMesh to only copy needed data */
/* set the Mesh to only copy needed data */
mask = curr->mask;
/* needMapping check here fixes bug [#28112], otherwise it's
* possible that it won't be copied */
mask |= append_mask;
DM_set_only_copy(dm, mask | (need_mapping ? CD_MASK_ORIGINDEX : 0));
mesh_set_only_copy(mesh, mask | (need_mapping ? CD_MASK_ORIGINDEX : 0));
/* add cloth rest shape key if needed */
if (mask & CD_MASK_CLOTH_ORCO)
add_orco_dm(ob, NULL, dm, clothorcodm, CD_CLOTH_ORCO);
add_orco_mesh(ob, NULL, mesh, orco_mesh, CD_CLOTH_ORCO);
/* add an origspace layer if needed */
if ((curr->mask) & CD_MASK_ORIGSPACE_MLOOP) {
if (!CustomData_has_layer(&dm->loopData, CD_ORIGSPACE_MLOOP)) {
DM_add_loop_layer(dm, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL);
DM_init_origspace(dm);
if (!CustomData_has_layer(&mesh->ldata, CD_ORIGSPACE_MLOOP)) {
CustomData_add_layer(&mesh->ldata, CD_ORIGSPACE_MLOOP, CD_CALLOC, NULL, mesh->totloop);
mesh_init_origspace(mesh);
}
}
ndm = modwrap_applyModifier(md, &mectx_apply, dm);
ASSERT_IS_VALID_DM(ndm);
Mesh *new_mesh = modifier_applyModifier_ensure_normals(md, &mectx_apply, mesh);
ASSERT_IS_VALID_MESH(new_mesh);
if (ndm) {
/* if the modifier returned a new dm, release the old one */
if (dm && dm != ndm) dm->release(dm);
if (new_mesh) {
/* if the modifier returned a new mesh, release the old one */
if (mesh && mesh != new_mesh) {
BKE_mesh_free(mesh);
MEM_freeN(mesh);
}
dm = ndm;
mesh = new_mesh;
if (deformedVerts) {
if (deformedVerts != inputVertexCos)
@@ -2085,43 +2347,48 @@ static void mesh_calc_modifiers(
}
}
/* create an orco derivedmesh in parallel */
/* create an orco mesh in parallel */
if (nextmask & CD_MASK_ORCO) {
if (!orcodm)
orcodm = create_orco_dm(ob, me, NULL, CD_ORCO);
if (!orco_mesh) {
orco_mesh = create_orco_mesh(ob, me, NULL, CD_ORCO);
}
nextmask &= ~CD_MASK_ORCO;
DM_set_only_copy(orcodm, nextmask | CD_MASK_ORIGINDEX |
mesh_set_only_copy(orco_mesh, nextmask | CD_MASK_ORIGINDEX |
(mti->requiredDataMask ?
mti->requiredDataMask(ob, md) : 0));
ndm = modwrap_applyModifier(md, &mectx_orco, orcodm);
ASSERT_IS_VALID_DM(ndm);
new_mesh = modifier_applyModifier_ensure_normals(md, &mectx_orco, orco_mesh);
ASSERT_IS_VALID_MESH(new_mesh);
if (ndm) {
/* if the modifier returned a new dm, release the old one */
if (orcodm && orcodm != ndm) orcodm->release(orcodm);
orcodm = ndm;
if (new_mesh) {
/* if the modifier returned a new mesh, release the old one */
if (orco_mesh && orco_mesh != new_mesh) {
BKE_id_free(NULL, orco_mesh);
}
orco_mesh = new_mesh;
}
}
/* create cloth orco derivedmesh in parallel */
/* create cloth orco mesh in parallel */
if (nextmask & CD_MASK_CLOTH_ORCO) {
if (!clothorcodm)
clothorcodm = create_orco_dm(ob, me, NULL, CD_CLOTH_ORCO);
if (!cloth_orco_mesh)
cloth_orco_mesh = create_orco_mesh(ob, me, NULL, CD_CLOTH_ORCO);
nextmask &= ~CD_MASK_CLOTH_ORCO;
DM_set_only_copy(clothorcodm, nextmask | CD_MASK_ORIGINDEX);
mesh_set_only_copy(cloth_orco_mesh, nextmask | CD_MASK_ORIGINDEX);
ndm = modwrap_applyModifier(md, &mectx_orco, clothorcodm);
ASSERT_IS_VALID_DM(ndm);
new_mesh = modifier_applyModifier_ensure_normals(md, &mectx_orco, cloth_orco_mesh);
ASSERT_IS_VALID_DM(new_mesh);
if (ndm) {
/* if the modifier returned a new dm, release the old one */
if (clothorcodm && clothorcodm != ndm) {
clothorcodm->release(clothorcodm);
if (new_mesh) {
/* if the modifier returned a new mesh, release the old one */
if (cloth_orco_mesh && cloth_orco_mesh != new_mesh) {
BKE_id_free(NULL, cloth_orco_mesh);
}
clothorcodm = ndm;
cloth_orco_mesh = new_mesh;
}
}
@@ -2131,11 +2398,11 @@ static void mesh_calc_modifiers(
append_mask |= CD_MASK_PREVIEW_MLOOPCOL;
/* In case of active preview modifier, make sure preview mask remains for following modifiers. */
else if ((md == previewmd) && (do_mod_wmcol)) {
DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL);
mesh_update_weight_mcol(ob, mesh, draw_flag, NULL, 0, NULL);
append_mask |= CD_MASK_PREVIEW_MLOOPCOL;
}
dm->deformedOnly = false;
// dm->deformedOnly = false; // XXX: Does Mesh need this? Looks to be used only by particle system
}
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
@@ -2152,65 +2419,60 @@ static void mesh_calc_modifiers(
for (md = firstmd; md; md = md->next)
modifier_freeTemporaryData(md);
/* Yay, we are done. If we have a DerivedMesh and deformed vertices
* need to apply these back onto the DerivedMesh. If we have no
* DerivedMesh then we need to build one.
/* Yay, we are done. If we have a Mesh and deformed vertices
* need to apply these back onto the Mesh. If we have no
* Mesh then we need to build one.
*/
if (dm && deformedVerts) {
finaldm = CDDM_copy(dm);
Mesh *final_mesh;
dm->release(dm);
if (mesh) {
final_mesh = mesh;
CDDM_apply_vert_coords(finaldm, deformedVerts);
if (deformedVerts) {
BKE_mesh_apply_vert_coords(final_mesh, deformedVerts);
}
#if 0 /* For later nice mod preview! */
/* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */
if (do_final_wmcol)
DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL);
#endif
}
else if (dm) {
finaldm = dm;
#if 0 /* For later nice mod preview! */
/* In case we need modified weights in CD_PREVIEW_MCOL, we have to re-compute it. */
if (do_final_wmcol)
DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL);
mesh_update_weight_mcol(ob, final_mesh, draw_flag, NULL, 0, NULL);
#endif
}
else {
finaldm = CDDM_from_mesh(me);
if (build_shapekey_layers) {
add_shapekey_layers(finaldm, me, ob);
}
BKE_id_copy_ex(NULL, &me->id, (ID**)&final_mesh,
LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_DEG_TAG, false);
//if (build_shapekey_layers) {
// add_shapekey_layers(final_mesh, me, ob);
//}
if (deformedVerts) {
CDDM_apply_vert_coords(finaldm, deformedVerts);
BKE_mesh_apply_vert_coords(final_mesh, deformedVerts);
}
/* In this case, we should never have weight-modifying modifiers in stack... */
if (do_init_wmcol)
DM_update_weight_mcol(ob, finaldm, draw_flag, NULL, 0, NULL);
mesh_update_weight_mcol(ob, final_mesh, draw_flag, NULL, 0, NULL);
}
/* add an orco layer if needed */
if (dataMask & CD_MASK_ORCO) {
add_orco_dm(ob, NULL, finaldm, orcodm, CD_ORCO);
add_orco_mesh(ob, NULL, final_mesh, orco_mesh, CD_ORCO);
if (r_deform && *r_deform)
add_orco_dm(ob, NULL, *r_deform, NULL, CD_ORCO);
if (r_deform_mesh && *r_deform_mesh)
add_orco_mesh(ob, NULL, *r_deform_mesh, NULL, CD_ORCO);
}
if (do_loop_normals) {
/* Compute loop normals (note: will compute poly and vert normals as well, if needed!) */
DM_calc_loop_normals(finaldm, do_loop_normals, loop_normals_split_angle);
BKE_mesh_calc_normals_split(final_mesh);
// dm->dirty |= DM_DIRTY_TESS_CDLAYERS; XXX
}
if (sculpt_dyntopo == false) {
/* watch this! after 2.75a we move to from tessface to looptri (by default) */
if (dataMask & CD_MASK_MFACE) {
DM_ensure_tessface(finaldm);
// DM_ensure_tessface(final_mesh); // XXX: port?
}
/* without this, drawing ngon tri's faces will show ugly tessellated face
@@ -2223,22 +2485,24 @@ static void mesh_calc_modifiers(
* If using loop normals, poly nors have already been computed.
*/
if (!do_loop_normals) {
dm_ensure_display_normals(finaldm);
mesh_ensure_display_normals(final_mesh);
}
}
/* Some modifiers, like datatransfer, may generate those data as temp layer, we do not want to keep them,
* as they are used by display code when available (i.e. even if autosmooth is disabled). */
if (!do_loop_normals && CustomData_has_layer(&finaldm->loopData, CD_NORMAL)) {
CustomData_free_layers(&finaldm->loopData, CD_NORMAL, finaldm->numLoopData);
if (!do_loop_normals && CustomData_has_layer(&final_mesh->ldata, CD_NORMAL)) {
CustomData_free_layers(&final_mesh->ldata, CD_NORMAL, final_mesh->totloop);
}
*r_final = finaldm;
*r_final_mesh = final_mesh;
if (orcodm)
orcodm->release(orcodm);
if (clothorcodm)
clothorcodm->release(clothorcodm);
if (orco_mesh) {
BKE_id_free(NULL, orco_mesh);
}
if (cloth_orco_mesh) {
BKE_id_free(NULL, cloth_orco_mesh);
}
if (deformedVerts && deformedVerts != inputVertexCos)
MEM_freeN(deformedVerts);
@@ -2246,6 +2510,30 @@ static void mesh_calc_modifiers(
BLI_linklist_free((LinkNode *)datamasks, NULL);
}
static void mesh_calc_modifiers_dm(
struct Depsgraph *depsgraph, Scene *scene, Object *ob, float (*inputVertexCos)[3],
const bool useRenderParams, int useDeform,
const bool need_mapping, CustomDataMask dataMask,
const int index, const bool useCache, const bool build_shapekey_layers,
const bool allow_gpu,
/* return args */
DerivedMesh **r_deformdm, DerivedMesh **r_finaldm)
{
Mesh *deform_mesh = NULL, *final_mesh = NULL;
mesh_calc_modifiers(depsgraph, scene, ob, inputVertexCos, useRenderParams, useDeform,
need_mapping, dataMask, index, useCache, build_shapekey_layers, allow_gpu,
(r_deformdm ? &deform_mesh : NULL), &final_mesh);
if(deform_mesh) {
*r_deformdm = CDDM_from_mesh_ex(deform_mesh, CD_DUPLICATE);
BKE_id_free(NULL, deform_mesh);
}
*r_finaldm = CDDM_from_mesh_ex(final_mesh, CD_DUPLICATE);
BKE_id_free(NULL, final_mesh);
}
float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *r_numVerts))[3]
{
BMIter iter;
@@ -2643,7 +2931,7 @@ static void mesh_build_data(
}
#endif
mesh_calc_modifiers(
mesh_calc_modifiers_dm(
depsgraph, scene, ob, NULL, false, 1, need_mapping, dataMask, -1, true, build_shapekey_layers,
true,
&ob->derivedDeform, &ob->derivedFinal);
@@ -2792,7 +3080,7 @@ DerivedMesh *mesh_create_derived_render(struct Depsgraph *depsgraph, Scene *scen
{
DerivedMesh *final;
mesh_calc_modifiers(
mesh_calc_modifiers_dm(
depsgraph, scene, ob, NULL, true, 1, false, dataMask, -1, false, false, false,
NULL, &final);
@@ -2803,7 +3091,7 @@ DerivedMesh *mesh_create_derived_index_render(struct Depsgraph *depsgraph, Scene
{
DerivedMesh *final;
mesh_calc_modifiers(
mesh_calc_modifiers_dm(
depsgraph, scene, ob, NULL, true, 1, false, dataMask, index, false, false, false,
NULL, &final);
@@ -2822,7 +3110,7 @@ DerivedMesh *mesh_create_derived_view(
*/
ob->transflag |= OB_NO_PSYS_UPDATE;
mesh_calc_modifiers(
mesh_calc_modifiers_dm(
depsgraph, scene, ob, NULL, false, 1, false, dataMask, -1, false, false, false,
NULL, &final);
@@ -2837,7 +3125,7 @@ DerivedMesh *mesh_create_derived_no_deform(
{
DerivedMesh *final;
mesh_calc_modifiers(
mesh_calc_modifiers_dm(
depsgraph, scene, ob, vertCos, false, 0, false, dataMask, -1, false, false, false,
NULL, &final);
@@ -2851,7 +3139,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(
{
DerivedMesh *final;
mesh_calc_modifiers(
mesh_calc_modifiers_dm(
depsgraph, scene, ob, vertCos, true, 0, false, dataMask, -1, false, false, false,
NULL, &final);
@@ -3149,6 +3437,76 @@ void DM_init_origspace(DerivedMesh *dm)
BLI_array_free(vcos_2d);
}
static void mesh_init_origspace(Mesh *mesh)
{
const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
OrigSpaceLoop *lof_array = CustomData_get_layer(&mesh->ldata, CD_ORIGSPACE_MLOOP);
const int numpoly = mesh->totpoly;
// const int numloop = mesh->totloop;
MVert *mv = mesh->mvert;
MLoop *ml = mesh->mloop;
MPoly *mp = mesh->mpoly;
int i, j, k;
float (*vcos_2d)[2] = NULL;
BLI_array_staticdeclare(vcos_2d, 64);
for (i = 0; i < numpoly; i++, mp++) {
OrigSpaceLoop *lof = lof_array + mp->loopstart;
if (mp->totloop == 3 || mp->totloop == 4) {
for (j = 0; j < mp->totloop; j++, lof++) {
copy_v2_v2(lof->uv, default_osf[j]);
}
}
else {
MLoop *l = &ml[mp->loopstart];
float p_nor[3], co[3];
float mat[3][3];
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
BKE_mesh_calc_poly_normal(mp, l, mv, p_nor);
axis_dominant_v3_to_m3(mat, p_nor);
BLI_array_clear(vcos_2d);
BLI_array_reserve(vcos_2d, mp->totloop);
for (j = 0; j < mp->totloop; j++, l++) {
mul_v3_m3v3(co, mat, mv[l->v].co);
copy_v2_v2(vcos_2d[j], co);
for (k = 0; k < 2; k++) {
if (co[k] > max[k])
max[k] = co[k];
else if (co[k] < min[k])
min[k] = co[k];
}
}
/* Brings min to (0, 0). */
negate_v2_v2(translate, min);
/* Scale will bring max to (1, 1). */
sub_v2_v2v2(scale, max, min);
if (scale[0] == 0.0f)
scale[0] = 1e-9f;
if (scale[1] == 0.0f)
scale[1] = 1e-9f;
invert_v2(scale);
/* Finally, transform all vcos_2d into ((0, 0), (1, 1)) square and assing them as origspace. */
for (j = 0; j < mp->totloop; j++, lof++) {
add_v2_v2v2(lof->uv, vcos_2d[j], translate);
mul_v2_v2(lof->uv, scale);
}
}
}
//mesh->dirty |= DM_DIRTY_TESS_CDLAYERS; // XXX: Needed for Mesh?
BLI_array_free(vcos_2d);
}
/* derivedmesh info printing function,

View File

@@ -972,7 +972,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, CustomData *edata,
}
/**
* \see #DM_is_valid to call on derived meshes
* Validates and corrects a Mesh.
*
* \returns true if a change is made.
*/
@@ -1011,6 +1011,42 @@ int BKE_mesh_validate(Mesh *me, const int do_verbose, const int cddata_check_mas
}
}
/**
* Checks if a Mesh is valid without any modification. This is always verbose.
*
* \see #DM_is_valid to call on derived meshes
*
* \returns is_valid.
*/
bool BKE_mesh_is_valid(Mesh *me)
{
const bool do_verbose = true;
const bool do_fixes = false;
bool is_valid = true;
bool changed = true;
is_valid &= BKE_mesh_validate_all_customdata(
&me->vdata, &me->edata, &me->ldata, &me->pdata,
false, /* setting mask here isn't useful, gives false positives */
do_verbose, do_fixes, &changed);
is_valid &= BKE_mesh_validate_arrays(
me,
me->mvert, me->totvert,
me->medge, me->totedge,
me->mface, me->totface,
me->mloop, me->totloop,
me->mpoly, me->totpoly,
me->dvert,
do_verbose, do_fixes,
&changed);
BLI_assert(changed == false);
return is_valid;
}
/**
* Check all material indices of polygons are valid, invalid ones are set to 0.
* \returns is_valid.

View File

@@ -901,6 +901,19 @@ void modifier_deformVerts(struct ModifierData *md, const ModifierEvalContext *ct
}
}
void modifier_deformVerts_ensure_normals(struct ModifierData *md, const ModifierEvalContext *ctx,
struct Mesh *mesh,
float (*vertexCos)[3], int numVerts)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
BLI_assert(!mesh || CustomData_has_layer(&mesh->pdata, CD_NORMAL) == false);
if (mesh && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
BKE_mesh_calc_normals(mesh);
}
modifier_deformVerts(md, ctx, mesh, vertexCos, numVerts);
}
void modifier_deformMatrices(struct ModifierData *md, const ModifierEvalContext *ctx,
struct Mesh *mesh,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
@@ -993,6 +1006,18 @@ struct Mesh *modifier_applyModifier(struct ModifierData *md, const ModifierEvalC
}
}
struct Mesh *modifier_applyModifier_ensure_normals(struct ModifierData *md, const ModifierEvalContext *ctx,
struct Mesh *mesh)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
BLI_assert(CustomData_has_layer(&mesh->pdata, CD_NORMAL) == false);
if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
BKE_mesh_calc_normals(mesh);
}
return modifier_applyModifier(md, ctx, mesh);
}
struct Mesh *modifier_applyModifierEM(struct ModifierData *md, const ModifierEvalContext *ctx,
struct BMEditMesh *editData,
struct Mesh *mesh)