2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2010-04-11 22:12:30 +00:00
|
|
|
* 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
|
2011-11-29 10:54:47 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2010-04-11 22:12:30 +00:00
|
|
|
*
|
2011-11-29 10:54:47 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
2010-04-11 22:12:30 +00:00
|
|
|
* 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
|
2011-11-29 10:54:47 +00:00
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-08-10 21:22:26 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2010-04-11 22:12:30 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*/
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup modifiers
|
2011-02-25 13:57:17 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2010-08-13 15:26:37 +00:00
|
|
|
#include <string.h>
|
2010-04-12 22:33:43 +00:00
|
|
|
|
2019-02-25 11:39:14 +01:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
|
|
|
#include "BLI_bitmap.h"
|
|
|
|
#include "BLI_math_vector.h"
|
|
|
|
#include "BLI_math_matrix.h"
|
|
|
|
|
2012-04-10 14:11:45 +00:00
|
|
|
#include "DNA_image_types.h"
|
|
|
|
#include "DNA_meshdata_types.h"
|
2018-04-19 11:03:58 +02:00
|
|
|
#include "DNA_mesh_types.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
#include "DNA_modifier_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
2012-04-10 14:11:45 +00:00
|
|
|
#include "DNA_scene_types.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2011-07-11 09:15:20 +00:00
|
|
|
#include "BKE_deform.h"
|
2018-05-08 11:33:31 +02:00
|
|
|
#include "BKE_editmesh.h"
|
2012-04-10 14:11:45 +00:00
|
|
|
#include "BKE_image.h"
|
2011-07-11 09:15:20 +00:00
|
|
|
#include "BKE_lattice.h"
|
2018-05-08 11:33:31 +02:00
|
|
|
#include "BKE_library.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
#include "BKE_mesh.h"
|
2018-12-14 16:07:29 +01:00
|
|
|
#include "BKE_object.h"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2010-04-25 01:10:03 +00:00
|
|
|
#include "BKE_modifier.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2018-05-23 15:52:35 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
|
|
|
#include "DEG_depsgraph_query.h"
|
|
|
|
|
2010-04-12 22:33:43 +00:00
|
|
|
#include "MOD_util.h"
|
2010-04-25 01:10:03 +00:00
|
|
|
#include "MOD_modifiertypes.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2010-04-12 22:33:43 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2018-05-08 11:33:31 +02:00
|
|
|
#include "bmesh.h"
|
|
|
|
|
2018-12-07 15:45:53 +01:00
|
|
|
void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *ctx)
|
2012-04-10 14:11:45 +00:00
|
|
|
{
|
2019-03-26 11:25:07 +01:00
|
|
|
Tex *tex = dmd->texture;
|
2018-12-07 15:45:53 +01:00
|
|
|
|
|
|
|
if (tex == NULL) {
|
2012-04-10 14:11:45 +00:00
|
|
|
return;
|
2018-12-07 15:45:53 +01:00
|
|
|
}
|
2012-04-10 14:11:45 +00:00
|
|
|
|
2014-01-14 04:59:58 +11:00
|
|
|
if (tex->ima && BKE_image_is_animated(tex->ima)) {
|
2018-12-07 15:45:53 +01:00
|
|
|
BKE_image_user_frame_calc(&tex->iuser, DEG_get_ctime(ctx->depsgraph));
|
2014-01-14 04:59:58 +11:00
|
|
|
}
|
2012-04-10 14:11:45 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 18:14:15 +02:00
|
|
|
/* TODO to be renamed to get_texture_coords once we are done with moving modifiers to Mesh. */
|
2018-12-12 12:55:20 +11:00
|
|
|
/** \param cos: may be NULL, in which case we use directly mesh vertices' coordinates. */
|
2018-06-29 19:02:19 +02:00
|
|
|
void MOD_get_texture_coords(
|
2018-05-07 18:14:15 +02:00
|
|
|
MappingInfoModifierData *dmd,
|
2019-03-26 11:25:07 +01:00
|
|
|
const ModifierEvalContext *UNUSED(ctx),
|
2018-05-07 18:14:15 +02:00
|
|
|
Object *ob,
|
|
|
|
Mesh *mesh,
|
2018-05-08 11:57:34 +02:00
|
|
|
float (*cos)[3],
|
2018-05-07 18:14:15 +02:00
|
|
|
float (*r_texco)[3])
|
|
|
|
{
|
|
|
|
const int numVerts = mesh->totvert;
|
|
|
|
int i;
|
|
|
|
int texmapping = dmd->texmapping;
|
|
|
|
float mapob_imat[4][4];
|
|
|
|
|
|
|
|
if (texmapping == MOD_DISP_MAP_OBJECT) {
|
2018-12-07 15:45:53 +01:00
|
|
|
if (dmd->map_object != NULL) {
|
2019-03-26 11:25:07 +01:00
|
|
|
Object *map_object = dmd->map_object;
|
2018-12-07 15:45:53 +01:00
|
|
|
invert_m4_m4(mapob_imat, map_object->obmat);
|
|
|
|
}
|
|
|
|
else {/* if there is no map object, default to local */
|
2018-05-07 18:14:15 +02:00
|
|
|
texmapping = MOD_DISP_MAP_LOCAL;
|
2018-12-07 15:45:53 +01:00
|
|
|
}
|
2018-05-07 18:14:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* UVs need special handling, since they come from faces */
|
|
|
|
if (texmapping == MOD_DISP_MAP_UV) {
|
|
|
|
if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
|
|
|
|
MPoly *mpoly = mesh->mpoly;
|
|
|
|
MPoly *mp;
|
|
|
|
MLoop *mloop = mesh->mloop;
|
|
|
|
BLI_bitmap *done = BLI_BITMAP_NEW(numVerts, __func__);
|
|
|
|
const int numPolys = mesh->totpoly;
|
|
|
|
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
|
|
|
|
MLoopUV *mloop_uv;
|
|
|
|
|
|
|
|
CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname);
|
|
|
|
mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
|
|
|
|
|
|
|
|
/* verts are given the UV from the first face that uses them */
|
|
|
|
for (i = 0, mp = mpoly; i < numPolys; ++i, ++mp) {
|
|
|
|
unsigned int fidx = mp->totloop - 1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
unsigned int lidx = mp->loopstart + fidx;
|
|
|
|
unsigned int vidx = mloop[lidx].v;
|
|
|
|
|
|
|
|
if (!BLI_BITMAP_TEST(done, vidx)) {
|
|
|
|
/* remap UVs from [0, 1] to [-1, 1] */
|
|
|
|
r_texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f;
|
|
|
|
r_texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f;
|
|
|
|
BLI_BITMAP_ENABLE(done, vidx);
|
|
|
|
}
|
|
|
|
|
|
|
|
} while (fidx--);
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(done);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* if there are no UVs, default to local */
|
|
|
|
texmapping = MOD_DISP_MAP_LOCAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
MVert *mv = mesh->mvert;
|
|
|
|
for (i = 0; i < numVerts; ++i, ++mv, ++r_texco) {
|
|
|
|
switch (texmapping) {
|
|
|
|
case MOD_DISP_MAP_LOCAL:
|
2018-05-08 11:57:34 +02:00
|
|
|
copy_v3_v3(*r_texco, cos != NULL ? *cos : mv->co);
|
2018-05-07 18:14:15 +02:00
|
|
|
break;
|
|
|
|
case MOD_DISP_MAP_GLOBAL:
|
2018-05-08 11:57:34 +02:00
|
|
|
mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
|
2018-05-07 18:14:15 +02:00
|
|
|
break;
|
|
|
|
case MOD_DISP_MAP_OBJECT:
|
2018-05-08 11:57:34 +02:00
|
|
|
mul_v3_m4v3(*r_texco, ob->obmat, cos != NULL ? *cos : mv->co);
|
2018-05-07 18:14:15 +02:00
|
|
|
mul_m4_v3(mapob_imat, *r_texco);
|
|
|
|
break;
|
|
|
|
}
|
2018-05-08 11:57:34 +02:00
|
|
|
if (cos != NULL) {
|
|
|
|
cos++;
|
|
|
|
}
|
2018-05-07 18:14:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-29 19:02:19 +02:00
|
|
|
void MOD_previous_vcos_store(ModifierData *md, float (*vertexCos)[3])
|
2010-04-11 22:12:30 +00:00
|
|
|
{
|
2012-05-06 13:38:33 +00:00
|
|
|
while ((md = md->next) && md->type == eModifierType_Armature) {
|
|
|
|
ArmatureModifierData *amd = (ArmatureModifierData *) md;
|
|
|
|
if (amd->multi && amd->prevCos == NULL)
|
|
|
|
amd->prevCos = MEM_dupallocN(vertexCos);
|
2010-04-11 22:12:30 +00:00
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* lattice/mesh modifier too */
|
|
|
|
}
|
|
|
|
|
2018-05-08 11:33:31 +02:00
|
|
|
/* returns a mesh if mesh == NULL, for deforming modifiers that need it */
|
2018-11-27 17:21:16 +01:00
|
|
|
Mesh *MOD_deform_mesh_eval_get(
|
2018-05-12 08:21:07 +02:00
|
|
|
Object *ob, struct BMEditMesh *em, Mesh *mesh,
|
2018-11-27 17:21:16 +01:00
|
|
|
float (*vertexCos)[3], const int num_verts,
|
|
|
|
const bool use_normals, const bool use_orco)
|
2018-05-08 11:33:31 +02:00
|
|
|
{
|
2018-11-27 17:21:16 +01:00
|
|
|
if (mesh != NULL) {
|
2018-05-08 11:33:31 +02:00
|
|
|
/* pass */
|
|
|
|
}
|
|
|
|
else if (ob->type == OB_MESH) {
|
2018-05-14 14:34:00 +02:00
|
|
|
if (em) {
|
Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
2019-03-07 11:13:40 +01:00
|
|
|
mesh = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
|
2018-05-14 14:34:00 +02:00
|
|
|
}
|
2018-05-08 11:33:31 +02:00
|
|
|
else {
|
2018-05-09 17:37:54 +02:00
|
|
|
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
|
|
|
|
* we really need a copy here. Maybe the CoW ob->data can be directly used. */
|
2018-12-14 16:07:29 +01:00
|
|
|
Mesh *mesh_prior_modifiers = BKE_object_get_pre_modified_mesh(ob);
|
2018-05-08 16:57:07 +02:00
|
|
|
BKE_id_copy_ex(
|
2018-12-14 16:07:29 +01:00
|
|
|
NULL, &mesh_prior_modifiers->id, (ID **)&mesh,
|
2019-02-04 17:51:15 +01:00
|
|
|
(LIB_ID_COPY_LOCALIZE |
|
2019-02-04 15:34:31 +01:00
|
|
|
LIB_ID_COPY_CD_REFERENCE));
|
2018-05-15 13:26:24 +02:00
|
|
|
mesh->runtime.deformed_only = 1;
|
2018-05-08 11:33:31 +02:00
|
|
|
}
|
|
|
|
|
2018-05-09 17:37:54 +02:00
|
|
|
/* TODO(sybren): after modifier conversion of DM to Mesh is done, check whether
|
|
|
|
* we really need vertexCos here. */
|
2018-05-08 11:33:31 +02:00
|
|
|
if (vertexCos) {
|
|
|
|
BKE_mesh_apply_vert_coords(mesh, vertexCos);
|
|
|
|
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (use_orco) {
|
|
|
|
CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob), mesh->totvert);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ELEM(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
|
|
|
|
/* TODO(sybren): get evaluated mesh from depsgraph once that's properly generated for curves. */
|
2018-05-08 17:28:43 +02:00
|
|
|
mesh = BKE_mesh_new_nomain_from_curve(ob);
|
2018-11-27 17:21:16 +01:00
|
|
|
|
|
|
|
/* Currently, that may not be the case everytime
|
|
|
|
* (texts e.g. tend to give issues, also when deforming curve points instead of generated curve geometry... ). */
|
|
|
|
if (mesh != NULL && mesh->totvert != num_verts) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
2018-11-27 20:40:04 +01:00
|
|
|
mesh = NULL;
|
2018-11-27 17:21:16 +01:00
|
|
|
}
|
2018-05-08 11:33:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (use_normals) {
|
|
|
|
if (LIKELY(mesh)) {
|
|
|
|
BKE_mesh_ensure_normals(mesh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-27 17:21:16 +01:00
|
|
|
BLI_assert(mesh == NULL || mesh->totvert == num_verts);
|
|
|
|
|
2018-05-08 11:33:31 +02:00
|
|
|
return mesh;
|
|
|
|
}
|
|
|
|
|
2018-06-29 19:02:19 +02:00
|
|
|
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
|
2018-04-19 11:03:58 +02:00
|
|
|
{
|
|
|
|
*defgrp_index = defgroup_name_index(ob, name);
|
|
|
|
*dvert = NULL;
|
|
|
|
|
|
|
|
if (*defgrp_index != -1) {
|
|
|
|
if (ob->type == OB_LATTICE)
|
|
|
|
*dvert = BKE_lattice_deform_verts_get(ob);
|
|
|
|
else if (mesh)
|
|
|
|
*dvert = mesh->dvert;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-30 13:06:48 +01:00
|
|
|
|
2010-04-25 01:10:03 +00:00
|
|
|
/* only called by BKE_modifier.h/modifier.c */
|
2010-10-14 06:29:17 +00:00
|
|
|
void modifier_type_init(ModifierTypeInfo *types[])
|
2010-04-25 01:10:03 +00:00
|
|
|
{
|
|
|
|
#define INIT_TYPE(typeName) (types[eModifierType_##typeName] = &modifierType_##typeName)
|
|
|
|
INIT_TYPE(None);
|
|
|
|
INIT_TYPE(Curve);
|
|
|
|
INIT_TYPE(Lattice);
|
|
|
|
INIT_TYPE(Subsurf);
|
|
|
|
INIT_TYPE(Build);
|
|
|
|
INIT_TYPE(Array);
|
|
|
|
INIT_TYPE(Mirror);
|
|
|
|
INIT_TYPE(EdgeSplit);
|
|
|
|
INIT_TYPE(Bevel);
|
|
|
|
INIT_TYPE(Displace);
|
|
|
|
INIT_TYPE(UVProject);
|
|
|
|
INIT_TYPE(Decimate);
|
|
|
|
INIT_TYPE(Smooth);
|
|
|
|
INIT_TYPE(Cast);
|
|
|
|
INIT_TYPE(Wave);
|
|
|
|
INIT_TYPE(Armature);
|
|
|
|
INIT_TYPE(Hook);
|
|
|
|
INIT_TYPE(Softbody);
|
|
|
|
INIT_TYPE(Cloth);
|
|
|
|
INIT_TYPE(Collision);
|
|
|
|
INIT_TYPE(Boolean);
|
|
|
|
INIT_TYPE(MeshDeform);
|
2011-11-13 12:17:27 +00:00
|
|
|
INIT_TYPE(Ocean);
|
2010-04-25 01:10:03 +00:00
|
|
|
INIT_TYPE(ParticleSystem);
|
|
|
|
INIT_TYPE(ParticleInstance);
|
|
|
|
INIT_TYPE(Explode);
|
|
|
|
INIT_TYPE(Shrinkwrap);
|
|
|
|
INIT_TYPE(Fluidsim);
|
|
|
|
INIT_TYPE(Mask);
|
|
|
|
INIT_TYPE(SimpleDeform);
|
|
|
|
INIT_TYPE(Multires);
|
|
|
|
INIT_TYPE(Surface);
|
|
|
|
INIT_TYPE(Smoke);
|
|
|
|
INIT_TYPE(ShapeKey);
|
|
|
|
INIT_TYPE(Solidify);
|
|
|
|
INIT_TYPE(Screw);
|
2011-05-01 15:16:59 +00:00
|
|
|
INIT_TYPE(Warp);
|
2011-07-25 15:27:01 +00:00
|
|
|
INIT_TYPE(WeightVGEdit);
|
|
|
|
INIT_TYPE(WeightVGMix);
|
|
|
|
INIT_TYPE(WeightVGProximity);
|
2011-05-24 07:08:58 +00:00
|
|
|
INIT_TYPE(DynamicPaint);
|
2011-12-30 21:11:40 +00:00
|
|
|
INIT_TYPE(Remesh);
|
2012-05-22 15:29:01 +00:00
|
|
|
INIT_TYPE(Skin);
|
2012-10-24 10:39:11 +00:00
|
|
|
INIT_TYPE(LaplacianSmooth);
|
2012-11-19 20:40:08 +00:00
|
|
|
INIT_TYPE(Triangulate);
|
2012-12-14 04:07:30 +00:00
|
|
|
INIT_TYPE(UVWarp);
|
2013-01-21 15:41:00 +00:00
|
|
|
INIT_TYPE(MeshCache);
|
2013-11-24 07:00:49 +11:00
|
|
|
INIT_TYPE(LaplacianDeform);
|
2013-12-22 07:08:35 +11:00
|
|
|
INIT_TYPE(Wireframe);
|
2015-01-09 21:19:12 +01:00
|
|
|
INIT_TYPE(DataTransfer);
|
2015-02-05 14:49:44 +01:00
|
|
|
INIT_TYPE(NormalEdit);
|
2015-03-29 04:44:05 +11:00
|
|
|
INIT_TYPE(CorrectiveSmooth);
|
Basic Alembic support
All in all, this patch adds an Alembic importer, an Alembic exporter,
and a new CacheFile data block which, for now, wraps around an Alembic
archive. This data block is made available through a new modifier ("Mesh
Sequence Cache") as well as a new constraint ("Transform Cache") to
somewhat properly support respectively geometric and transformation data
streaming from alembic caches.
A more in-depth documentation is to be found on the wiki, as well as a
guide to compile alembic: https://wiki.blender.org/index.php/
User:Kevindietrich/AlembicBasicIo.
Many thanks to everyone involved in this little project, and huge shout
out to "cgstrive" for the thorough testings with Maya, 3ds Max, Houdini
and Realflow as well as @fjuhec, @jensverwiebe and @jasperge for the
custom builds and compile fixes.
Reviewers: sergey, campbellbarton, mont29
Reviewed By: sergey, campbellbarton, mont29
Differential Revision: https://developer.blender.org/D2060
2016-08-06 06:20:37 +02:00
|
|
|
INIT_TYPE(MeshSequenceCache);
|
2017-02-27 12:39:14 -03:00
|
|
|
INIT_TYPE(SurfaceDeform);
|
2018-05-25 22:24:24 +05:30
|
|
|
INIT_TYPE(WeightedNormal);
|
2010-04-25 01:10:03 +00:00
|
|
|
#undef INIT_TYPE
|
|
|
|
}
|