|
|
|
@@ -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,
|
|
|
|
|