2006-08-28 01:12:36 +00:00
|
|
|
/*
|
2011-10-10 09:38:02 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s): Daniel Dunbar
|
|
|
|
* Ton Roosendaal,
|
|
|
|
* Ben Batt,
|
|
|
|
* Brecht Van Lommel,
|
|
|
|
* Campbell Barton
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* Modifier stack implementation.
|
|
|
|
*
|
|
|
|
* BKE_modifier.h contains the function prototypes for this file.
|
|
|
|
*
|
|
|
|
*/
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2011-02-27 20:40:57 +00:00
|
|
|
/** \file blender/blenkernel/intern/modifier.c
|
|
|
|
* \ingroup bke
|
|
|
|
*/
|
|
|
|
|
2013-06-19 08:00:20 +00:00
|
|
|
#include <stdlib.h>
|
2010-08-13 15:26:37 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
2005-07-19 20:14:17 +00:00
|
|
|
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2005-10-20 16:31:46 +00:00
|
|
|
#include "DNA_armature_types.h"
|
2018-04-18 15:45:54 +02:00
|
|
|
#include "DNA_mesh_types.h"
|
2010-08-10 05:41:51 +00:00
|
|
|
#include "DNA_object_types.h"
|
2005-07-19 20:14:17 +00:00
|
|
|
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2011-10-20 13:50:24 +00:00
|
|
|
#include "BLI_listbase.h"
|
2011-10-22 01:53:35 +00:00
|
|
|
#include "BLI_linklist.h"
|
2017-01-16 17:33:34 +01:00
|
|
|
#include "BLI_path_util.h"
|
2011-10-20 13:50:24 +00:00
|
|
|
#include "BLI_string.h"
|
2017-01-16 17:33:34 +01:00
|
|
|
#include "BLI_string_utils.h"
|
2010-08-16 05:46:10 +00:00
|
|
|
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2012-10-27 11:12:09 +00:00
|
|
|
|
2014-11-23 14:37:13 +01:00
|
|
|
#include "BKE_appdir.h"
|
2018-04-18 15:45:54 +02:00
|
|
|
#include "BKE_cdderivedmesh.h"
|
2018-05-30 11:34:08 +02:00
|
|
|
#include "BKE_editmesh.h"
|
2018-05-31 15:24:30 +02:00
|
|
|
#include "BKE_global.h"
|
2018-05-03 15:42:55 +02:00
|
|
|
#include "BKE_idcode.h"
|
2009-10-22 16:35:51 +00:00
|
|
|
#include "BKE_key.h"
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
#include "BKE_library.h"
|
|
|
|
#include "BKE_library_query.h"
|
2018-04-18 15:45:54 +02:00
|
|
|
#include "BKE_mesh.h"
|
2010-09-09 00:14:51 +00:00
|
|
|
#include "BKE_multires.h"
|
2018-05-25 12:27:54 +02:00
|
|
|
#include "BKE_object.h"
|
2013-06-19 08:00:20 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2011-11-20 14:38:11 +00:00
|
|
|
/* may move these, only for modifier_path_relbase */
|
|
|
|
#include "BKE_main.h"
|
|
|
|
/* end */
|
|
|
|
|
2018-02-06 19:34:36 +11:00
|
|
|
#include "DEG_depsgraph.h"
|
2018-05-24 16:40:08 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
2018-02-06 19:34:36 +11:00
|
|
|
|
2010-04-11 22:12:30 +00:00
|
|
|
#include "MOD_modifiertypes.h"
|
2009-06-09 13:03:00 +00:00
|
|
|
|
2013-08-19 09:05:34 +00:00
|
|
|
static ModifierTypeInfo *modifier_types[NUM_MODIFIER_TYPES] = {NULL};
|
|
|
|
static VirtualModifierData virtualModifierCommonData;
|
|
|
|
|
|
|
|
void BKE_modifier_init(void)
|
2009-06-09 13:03:00 +00:00
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
ModifierData *md;
|
2009-06-09 13:03:00 +00:00
|
|
|
|
2013-08-19 09:05:34 +00:00
|
|
|
/* Initialize modifier types */
|
|
|
|
modifier_type_init(modifier_types); /* MOD_utils.c */
|
|
|
|
|
|
|
|
/* Initialize global cmmon storage used for virtual modifier list */
|
|
|
|
md = modifier_new(eModifierType_Armature);
|
|
|
|
virtualModifierCommonData.amd = *((ArmatureModifierData *) md);
|
|
|
|
modifier_free(md);
|
|
|
|
|
|
|
|
md = modifier_new(eModifierType_Curve);
|
|
|
|
virtualModifierCommonData.cmd = *((CurveModifierData *) md);
|
|
|
|
modifier_free(md);
|
2009-06-09 13:03:00 +00:00
|
|
|
|
2013-08-19 09:05:34 +00:00
|
|
|
md = modifier_new(eModifierType_Lattice);
|
|
|
|
virtualModifierCommonData.lmd = *((LatticeModifierData *) md);
|
|
|
|
modifier_free(md);
|
|
|
|
|
|
|
|
md = modifier_new(eModifierType_ShapeKey);
|
|
|
|
virtualModifierCommonData.smd = *((ShapeKeyModifierData *) md);
|
|
|
|
modifier_free(md);
|
|
|
|
|
|
|
|
virtualModifierCommonData.amd.modifier.mode |= eModifierMode_Virtual;
|
|
|
|
virtualModifierCommonData.cmd.modifier.mode |= eModifierMode_Virtual;
|
|
|
|
virtualModifierCommonData.lmd.modifier.mode |= eModifierMode_Virtual;
|
|
|
|
virtualModifierCommonData.smd.modifier.mode |= eModifierMode_Virtual;
|
|
|
|
}
|
|
|
|
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
2013-08-19 09:05:34 +00:00
|
|
|
{
|
2012-04-21 15:11:03 +00:00
|
|
|
/* type unsigned, no need to check < 0 */
|
2013-08-19 09:05:34 +00:00
|
|
|
if (type < NUM_MODIFIER_TYPES && modifier_types[type]->name[0] != '\0') {
|
|
|
|
return modifier_types[type];
|
2010-01-06 12:05:46 +00:00
|
|
|
}
|
|
|
|
else {
|
2005-07-19 20:14:17 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
/***/
|
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
ModifierData *modifier_new(int type)
|
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(type);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
ModifierData *md = MEM_callocN(mti->structSize, mti->structName);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2011-10-19 23:10:54 +00:00
|
|
|
/* note, this name must be made unique later */
|
2013-03-20 18:42:09 +00:00
|
|
|
BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
md->type = type;
|
2012-05-09 09:24:15 +00:00
|
|
|
md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded;
|
2018-05-02 18:13:15 +02:00
|
|
|
md->flag = eModifierFlag_StaticOverride_Local;
|
2005-07-23 19:15:08 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
if (mti->flags & eModifierTypeFlag_EnableInEditmode)
|
2005-07-23 19:15:08 +00:00
|
|
|
md->mode |= eModifierMode_Editmode;
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
|
|
|
if (mti->initData) mti->initData(md);
|
|
|
|
|
|
|
|
return md;
|
|
|
|
}
|
|
|
|
|
2018-04-04 14:56:32 +02:00
|
|
|
static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
|
|
|
|
{
|
|
|
|
ID *id = *idpoin;
|
|
|
|
if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
|
|
|
|
id_us_min(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void modifier_free_ex(ModifierData *md, const int flag)
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
2018-04-04 14:56:32 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
if (mti->foreachIDLink) {
|
|
|
|
mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL);
|
|
|
|
}
|
|
|
|
else if (mti->foreachObjectLink) {
|
|
|
|
mti->foreachObjectLink(md, NULL, (ObjectWalkFunc)modifier_free_data_id_us_cb, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (mti->freeData) mti->freeData(md);
|
2005-08-04 07:25:43 +00:00
|
|
|
if (md->error) MEM_freeN(md->error);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
|
|
|
MEM_freeN(md);
|
|
|
|
}
|
|
|
|
|
2018-04-04 14:56:32 +02:00
|
|
|
void modifier_free(ModifierData *md)
|
|
|
|
{
|
|
|
|
modifier_free_ex(md, 0);
|
|
|
|
}
|
|
|
|
|
2015-02-13 13:44:13 +05:00
|
|
|
bool modifier_unique_name(ListBase *modifiers, ModifierData *md)
|
2009-10-09 09:48:04 +00:00
|
|
|
{
|
|
|
|
if (modifiers && md) {
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2013-03-25 08:29:06 +00:00
|
|
|
|
2015-02-13 13:44:13 +05:00
|
|
|
return BLI_uniquename(modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name));
|
2009-10-09 09:48:04 +00:00
|
|
|
}
|
2015-02-13 13:44:13 +05:00
|
|
|
return false;
|
2009-10-09 09:48:04 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_dependsOnTime(ModifierData *md)
|
2005-07-20 04:14:21 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2005-07-20 04:14:21 +00:00
|
|
|
|
|
|
|
return mti->dependsOnTime && mti->dependsOnTime(md);
|
|
|
|
}
|
2005-07-27 20:16:41 +00:00
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_supportsMapping(ModifierData *md)
|
2005-08-03 04:04:05 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2005-08-03 04:04:05 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
return (mti->type == eModifierTypeType_OnlyDeform ||
|
|
|
|
(mti->flags & eModifierTypeFlag_SupportsMapping));
|
2005-08-03 04:04:05 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_isPreview(ModifierData *md)
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
|
2014-08-15 10:07:39 +02:00
|
|
|
/* Constructive modifiers are highly likely to also modify data like vgroups or vcol! */
|
|
|
|
if (!((mti->flags & eModifierTypeFlag_UsesPreview) || (mti->type == eModifierTypeType_Constructive))) {
|
2014-03-20 22:56:28 +11:00
|
|
|
return false;
|
2014-08-15 10:07:39 +02:00
|
|
|
}
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
|
2014-08-15 10:07:39 +02:00
|
|
|
if (md->mode & eModifierMode_Realtime) {
|
2014-03-20 22:56:28 +11:00
|
|
|
return true;
|
2014-08-15 10:07:39 +02:00
|
|
|
}
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
|
2014-03-20 22:56:28 +11:00
|
|
|
return false;
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
}
|
|
|
|
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
ModifierData *modifiers_findByType(Object *ob, ModifierType type)
|
2005-07-27 20:16:41 +00:00
|
|
|
{
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
ModifierData *md = ob->modifiers.first;
|
2005-07-27 20:16:41 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next)
|
|
|
|
if (md->type == type)
|
2005-07-27 20:16:41 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
return md;
|
|
|
|
}
|
|
|
|
|
2010-04-22 01:55:10 +00:00
|
|
|
ModifierData *modifiers_findByName(Object *ob, const char *name)
|
|
|
|
{
|
2010-04-22 08:25:05 +00:00
|
|
|
return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
|
2010-04-22 01:55:10 +00:00
|
|
|
}
|
|
|
|
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
void modifiers_clearErrors(Object *ob)
|
2005-08-04 07:25:43 +00:00
|
|
|
{
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
ModifierData *md = ob->modifiers.first;
|
2011-01-08 12:43:44 +00:00
|
|
|
/* int qRedraw = 0; */
|
2005-08-04 07:25:43 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2005-08-04 07:25:43 +00:00
|
|
|
if (md->error) {
|
|
|
|
MEM_freeN(md->error);
|
|
|
|
md->error = NULL;
|
|
|
|
|
2011-01-08 12:43:44 +00:00
|
|
|
/* qRedraw = 1; */
|
2005-08-04 07:25:43 +00:00
|
|
|
}
|
|
|
|
}
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
}
|
|
|
|
|
2015-10-08 14:21:11 +02:00
|
|
|
void modifiers_foreachObjectLink(Object *ob, ObjectWalkFunc walk, void *userData)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = ob->modifiers.first;
|
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
if (mti->foreachObjectLink)
|
|
|
|
mti->foreachObjectLink(md, ob, walk, userData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void modifiers_foreachIDLink(Object *ob, IDWalkFunc walk, void *userData)
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = ob->modifiers.first;
|
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData);
|
|
|
|
else if (mti->foreachObjectLink) {
|
2006-08-28 01:12:36 +00:00
|
|
|
/* each Object can masquerade as an ID, so this should be OK */
|
|
|
|
ObjectWalkFunc fp = (ObjectWalkFunc)walk;
|
|
|
|
mti->foreachObjectLink(md, ob, fp, userData);
|
|
|
|
}
|
- added eModifierTypeFlag_RequiresOriginalData for modifiers that
can only follow deform (for example, they store mesh vertex
indices)
- added ModifierType.foreachObjectLink for iterating over Object
links inside modifier data (used for file load, relinking, etc)
- switched various modifiers_ functions to take object argument
instead of ListBase
- added user editable name field to modifiers
- bug fix, duplicate and make single user didn't relink object
pointers in modifier data
- added modifiers to outliner, needs icon
- added armature, hook, and softbody modifiers (softbody doesn't
do anything atm). added conversion of old hooks to modifiers.
NOTE-THE-FIRST: User name field is not initialized on loading 2.38 files
so if you have saved stuff with a cvs blender you will see blank names.
NOTE-THE-SECOND: Since modifiers aren't evaluated yet for non-Mesh
objects, hooks for lattices and curves are broken. Don't updated if
you actually, say, *use* Blender.
NOTE-THE-THIRD: Old hooks used a quirky weighting system during
deformation which can't be extended to modifiers. On the upside,
I doubt anyone relied on the old quirky system and the new system
makes much more sense. (Although the way falloff works is still
quite stupid I think).
2005-08-10 22:05:52 +00:00
|
|
|
}
|
2005-08-04 07:25:43 +00:00
|
|
|
}
|
|
|
|
|
2011-08-12 18:11:22 +00:00
|
|
|
void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData)
|
|
|
|
{
|
|
|
|
ModifierData *md = ob->modifiers.first;
|
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2011-08-12 18:11:22 +00:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (mti->foreachTexLink)
|
2011-08-12 18:11:22 +00:00
|
|
|
mti->foreachTexLink(md, ob, walk, userData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-22 04:35:52 +11:00
|
|
|
/* callback's can use this
|
|
|
|
* to avoid copying every member.
|
|
|
|
*/
|
2018-07-04 12:45:30 +02:00
|
|
|
void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst, const int UNUSED(flag))
|
2013-12-22 04:35:52 +11:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md_src->type);
|
2018-05-07 17:58:35 +02:00
|
|
|
|
2018-09-24 17:27:41 +02:00
|
|
|
/* md_dst may have already be fully initialized with some extra allocated data,
|
2018-05-07 17:58:35 +02:00
|
|
|
* we need to free it now to avoid memleak. */
|
|
|
|
if (mti->freeData) {
|
|
|
|
mti->freeData(md_dst);
|
|
|
|
}
|
|
|
|
|
2013-12-22 04:35:52 +11:00
|
|
|
const size_t data_size = sizeof(ModifierData);
|
2015-01-14 05:10:18 +11:00
|
|
|
const char *md_src_data = ((const char *)md_src) + data_size;
|
|
|
|
char *md_dst_data = ((char *)md_dst) + data_size;
|
2013-12-22 04:35:52 +11:00
|
|
|
BLI_assert(data_size <= (size_t)mti->structSize);
|
|
|
|
memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
|
|
|
|
}
|
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
static void modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
|
|
|
|
{
|
|
|
|
ID *id = *idpoin;
|
|
|
|
if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
|
|
|
|
id_us_plus(id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag)
|
2005-07-27 20:16:41 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2005-07-27 20:16:41 +00:00
|
|
|
|
|
|
|
target->mode = md->mode;
|
2018-05-02 18:13:15 +02:00
|
|
|
target->flag = md->flag;
|
2005-07-27 20:16:41 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
if (mti->copyData) {
|
2018-07-04 12:45:30 +02:00
|
|
|
mti->copyData(md, target, flag);
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
if (mti->foreachIDLink) {
|
|
|
|
mti->foreachIDLink(target, NULL, modifier_copy_data_id_us_cb, NULL);
|
|
|
|
}
|
|
|
|
else if (mti->foreachObjectLink) {
|
|
|
|
mti->foreachObjectLink(target, NULL, (ObjectWalkFunc)modifier_copy_data_id_us_cb, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void modifier_copyData(ModifierData *md, ModifierData *target)
|
|
|
|
{
|
|
|
|
modifier_copyData_ex(md, target, 0);
|
2005-07-27 20:16:41 +00:00
|
|
|
}
|
2005-08-04 07:25:43 +00:00
|
|
|
|
2013-12-13 20:57:36 +01:00
|
|
|
|
|
|
|
bool modifier_supportsCage(struct Scene *scene, ModifierData *md)
|
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2013-12-13 20:57:36 +01:00
|
|
|
|
2018-06-21 17:54:12 +02:00
|
|
|
return ((!mti->isDisabled || !mti->isDisabled(scene, md, 0)) &&
|
2013-12-18 15:35:31 +11:00
|
|
|
(mti->flags & eModifierTypeFlag_SupportsEditmode) &&
|
|
|
|
modifier_supportsMapping(md));
|
2013-12-13 20:57:36 +01:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_couldBeCage(struct Scene *scene, ModifierData *md)
|
2005-08-04 07:25:43 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2005-08-04 07:25:43 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
return ((md->mode & eModifierMode_Realtime) &&
|
|
|
|
(md->mode & eModifierMode_Editmode) &&
|
2018-06-21 17:54:12 +02:00
|
|
|
(!mti->isDisabled || !mti->isDisabled(scene, md, 0)) &&
|
2012-05-06 17:22:54 +00:00
|
|
|
modifier_supportsMapping(md));
|
2005-08-04 07:25:43 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_isSameTopology(ModifierData *md)
|
2009-11-22 13:44:09 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2012-05-20 15:00:19 +00:00
|
|
|
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
|
2011-12-20 14:15:59 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_isNonGeometrical(ModifierData *md)
|
2011-12-20 14:15:59 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2011-12-20 14:15:59 +00:00
|
|
|
return (mti->type == eModifierTypeType_NonGeometrical);
|
2009-11-22 13:44:09 +00:00
|
|
|
}
|
|
|
|
|
2012-10-27 11:12:09 +00:00
|
|
|
void modifier_setError(ModifierData *md, const char *_format, ...)
|
2005-08-04 07:25:43 +00:00
|
|
|
{
|
2011-02-12 16:54:24 +00:00
|
|
|
char buffer[512];
|
2005-08-04 07:25:43 +00:00
|
|
|
va_list ap;
|
2012-10-27 11:12:09 +00:00
|
|
|
const char *format = TIP_(_format);
|
2005-08-04 07:25:43 +00:00
|
|
|
|
2012-10-27 11:12:09 +00:00
|
|
|
va_start(ap, _format);
|
2011-02-12 16:54:24 +00:00
|
|
|
vsnprintf(buffer, sizeof(buffer), format, ap);
|
2005-08-04 07:25:43 +00:00
|
|
|
va_end(ap);
|
2012-05-06 17:22:54 +00:00
|
|
|
buffer[sizeof(buffer) - 1] = '\0';
|
2005-08-04 07:25:43 +00:00
|
|
|
|
|
|
|
if (md->error)
|
|
|
|
MEM_freeN(md->error);
|
|
|
|
|
|
|
|
md->error = BLI_strdup(buffer);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
/* used for buttons, to find out if the 'draw deformed in editmode' option is
|
|
|
|
* there
|
2018-06-01 18:19:39 +02:00
|
|
|
*
|
2006-08-28 01:12:36 +00:00
|
|
|
* also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
|
2018-06-01 18:19:39 +02:00
|
|
|
* then is NULL)
|
2010-12-21 15:10:09 +00:00
|
|
|
* also used for some mesh tools to give warnings
|
2006-08-28 01:12:36 +00:00
|
|
|
*/
|
2014-03-16 03:24:05 +11:00
|
|
|
int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
|
2005-08-04 07:25:43 +00:00
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
2014-03-16 03:24:05 +11:00
|
|
|
ModifierData *md = (is_virtual) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first;
|
2005-08-04 07:25:43 +00:00
|
|
|
int i, cageIndex = -1;
|
|
|
|
|
2014-03-16 03:24:05 +11:00
|
|
|
if (r_lastPossibleCageIndex) {
|
2011-02-22 12:19:27 +00:00
|
|
|
/* ensure the value is initialized */
|
2014-03-16 03:24:05 +11:00
|
|
|
*r_lastPossibleCageIndex = -1;
|
2011-02-22 12:19:27 +00:00
|
|
|
}
|
|
|
|
|
2008-04-08 12:58:25 +00:00
|
|
|
/* Find the last modifier acting on the cage. */
|
2012-05-06 17:22:54 +00:00
|
|
|
for (i = 0; md; i++, md = md->next) {
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2014-08-17 09:35:57 +02:00
|
|
|
bool supports_mapping;
|
2005-08-04 07:25:43 +00:00
|
|
|
|
2018-06-21 17:54:12 +02:00
|
|
|
if (mti->isDisabled && mti->isDisabled(scene, md, 0)) continue;
|
2006-08-28 01:12:36 +00:00
|
|
|
if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
|
2007-07-28 21:04:30 +00:00
|
|
|
if (md->mode & eModifierMode_DisableTemporary) continue;
|
2005-08-04 07:25:43 +00:00
|
|
|
|
2014-08-17 09:35:57 +02:00
|
|
|
supports_mapping = modifier_supportsMapping(md);
|
|
|
|
if (r_lastPossibleCageIndex && supports_mapping) {
|
|
|
|
*r_lastPossibleCageIndex = i;
|
|
|
|
}
|
|
|
|
|
2014-05-30 20:22:23 +02:00
|
|
|
if (!(md->mode & eModifierMode_Realtime)) continue;
|
|
|
|
if (!(md->mode & eModifierMode_Editmode)) continue;
|
|
|
|
|
2014-08-17 09:35:57 +02:00
|
|
|
if (!supports_mapping)
|
2005-08-04 07:25:43 +00:00
|
|
|
break;
|
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
if (md->mode & eModifierMode_OnCage)
|
2005-08-04 07:25:43 +00:00
|
|
|
cageIndex = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cageIndex;
|
|
|
|
}
|
2005-08-11 02:23:52 +00:00
|
|
|
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifiers_isSoftbodyEnabled(Object *ob)
|
2005-08-11 02:23:52 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody);
|
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
2005-08-11 02:23:52 +00:00
|
|
|
}
|
2005-08-11 03:31:33 +00:00
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifiers_isClothEnabled(Object *ob)
|
2008-01-29 21:01:12 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth);
|
|
|
|
|
|
|
|
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifiers_isModifierEnabled(Object *ob, int modifierType)
|
2012-07-04 16:55:17 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = modifiers_findByType(ob, modifierType);
|
|
|
|
|
|
|
|
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifiers_isParticleEnabled(Object *ob)
|
Particles
=========
Merge of the famous particle patch by Janne Karhu, a full rewrite
of the Blender particle system. This includes:
- Emitter, Hair and Reactor particle types.
- Newtonian, Keyed and Boids physics.
- Various particle visualisation and rendering types.
- Vertex group and texture control for various properties.
- Interpolated child particles from parents.
- Hair editing with combing, growing, cutting, .. .
- Explode modifier.
- Harmonic, Magnetic fields, and multiple falloff types.
.. and lots of other things, some more info is here:
http://wiki.blender.org/index.php/BlenderDev/Particles_Rewrite
http://wiki.blender.org/index.php/BlenderDev/Particles_Rewrite_Doc
The new particle system cannot be backwards compatible. Old particle
systems are being converted to the new system, but will require
tweaking to get them looking the same as before.
Point Cache
===========
The new system to replace manual baking, based on automatic caching
on disk. This is currently used by softbodies and the particle system.
See the Cache API section on:
http://wiki.blender.org/index.php/BlenderDev/PhysicsSprint
Documentation
=============
These new features still need good docs for the release logs, help
for this is appreciated.
2007-11-26 22:09:57 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem);
|
|
|
|
|
|
|
|
return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render));
|
|
|
|
}
|
|
|
|
|
2018-01-24 11:12:01 +01:00
|
|
|
/**
|
|
|
|
* Check whether is enabled.
|
|
|
|
*
|
|
|
|
* \param scene Current scene, may be NULL, in which case isDisabled callback of the modifier is never called.
|
|
|
|
*/
|
2018-06-21 17:54:12 +02:00
|
|
|
bool modifier_isEnabled(const struct Scene *scene, ModifierData *md, int required_mode)
|
2009-06-15 11:48:42 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2009-06-15 11:48:42 +00:00
|
|
|
|
2014-08-20 20:41:30 +02:00
|
|
|
if ((md->mode & required_mode) != required_mode) return false;
|
2018-06-21 17:54:12 +02:00
|
|
|
if (scene != NULL && mti->isDisabled && mti->isDisabled(scene, md, required_mode == eModifierMode_Render)) return false;
|
2014-08-20 20:41:30 +02:00
|
|
|
if (md->mode & eModifierMode_DisableTemporary) return false;
|
|
|
|
if ((required_mode & eModifierMode_Editmode) && !(mti->flags & eModifierTypeFlag_SupportsEditmode)) return false;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-08-20 20:41:30 +02:00
|
|
|
return true;
|
2009-06-15 11:48:42 +00:00
|
|
|
}
|
|
|
|
|
2013-06-13 00:33:48 +00:00
|
|
|
CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md,
|
|
|
|
CustomDataMask dataMask, int required_mode,
|
|
|
|
ModifierData *previewmd, CustomDataMask previewmask)
|
2006-12-05 17:42:03 +00:00
|
|
|
{
|
2012-03-26 16:25:21 +00:00
|
|
|
CDMaskLink *dataMasks = NULL;
|
|
|
|
CDMaskLink *curr, *prev;
|
2006-12-05 17:42:03 +00:00
|
|
|
|
|
|
|
/* build a list of modifier data requirements in reverse order */
|
2012-03-24 06:18:31 +00:00
|
|
|
for (; md; md = md->next) {
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2006-12-05 17:42:03 +00:00
|
|
|
|
2012-03-26 16:25:21 +00:00
|
|
|
curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink");
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2013-06-13 00:33:48 +00:00
|
|
|
if (modifier_isEnabled(scene, md, required_mode)) {
|
2012-03-24 06:18:31 +00:00
|
|
|
if (mti->requiredDataMask)
|
2012-03-26 16:25:21 +00:00
|
|
|
curr->mask = mti->requiredDataMask(ob, md);
|
2006-12-05 17:42:03 +00:00
|
|
|
|
2013-06-13 00:33:48 +00:00
|
|
|
if (previewmd == md) {
|
|
|
|
curr->mask |= previewmask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-26 16:25:21 +00:00
|
|
|
/* prepend new datamask */
|
|
|
|
curr->next = dataMasks;
|
|
|
|
dataMasks = curr;
|
2006-12-05 17:42:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* build the list of required data masks - each mask in the list must
|
2012-03-03 20:19:11 +00:00
|
|
|
* include all elements of the masks that follow it
|
|
|
|
*
|
|
|
|
* note the list is currently in reverse order, so "masks that follow it"
|
|
|
|
* actually means "masks that precede it" at the moment
|
|
|
|
*/
|
2012-03-24 06:18:31 +00:00
|
|
|
for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
|
|
|
|
if (prev) {
|
2012-03-26 16:25:21 +00:00
|
|
|
CustomDataMask prev_mask = prev->mask;
|
|
|
|
CustomDataMask curr_mask = curr->mask;
|
2006-12-05 17:42:03 +00:00
|
|
|
|
2012-03-26 16:25:21 +00:00
|
|
|
curr->mask = curr_mask | prev_mask;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-26 16:25:21 +00:00
|
|
|
CustomDataMask curr_mask = curr->mask;
|
2006-12-05 17:42:03 +00:00
|
|
|
|
2012-03-26 16:25:21 +00:00
|
|
|
curr->mask = curr_mask | dataMask;
|
2006-12-05 17:42:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* reverse the list so it's in the correct order */
|
2012-05-06 17:22:54 +00:00
|
|
|
BLI_linklist_reverse((LinkNode **)&dataMasks);
|
2006-12-05 17:42:03 +00:00
|
|
|
|
|
|
|
return dataMasks;
|
|
|
|
}
|
|
|
|
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode)
|
|
|
|
{
|
|
|
|
ModifierData *tmp_md = NULL;
|
|
|
|
|
2013-07-04 22:24:39 +00:00
|
|
|
if ((required_mode & ~eModifierMode_Editmode) != eModifierMode_Realtime)
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
return tmp_md;
|
|
|
|
|
|
|
|
/* Find the latest modifier in stack generating preview. */
|
2012-03-24 06:18:31 +00:00
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md))
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
tmp_md = md;
|
|
|
|
}
|
|
|
|
return tmp_md;
|
|
|
|
}
|
|
|
|
|
2013-03-02 07:27:19 +00:00
|
|
|
/* NOTE: This is to support old files from before Blender supported modifiers,
|
|
|
|
* in some cases versioning code updates these so for new files this will
|
|
|
|
* return an empty list. */
|
2013-08-19 09:05:34 +00:00
|
|
|
ModifierData *modifiers_getVirtualModifierList(Object *ob, VirtualModifierData *virtualModifierData)
|
2005-08-11 03:31:33 +00:00
|
|
|
{
|
2009-10-22 16:35:51 +00:00
|
|
|
ModifierData *md;
|
2005-08-11 03:31:33 +00:00
|
|
|
|
2009-10-22 16:35:51 +00:00
|
|
|
md = ob->modifiers.first;
|
|
|
|
|
2013-08-19 09:05:34 +00:00
|
|
|
*virtualModifierData = virtualModifierCommonData;
|
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (ob->parent) {
|
2012-05-06 17:22:54 +00:00
|
|
|
if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
|
2013-08-19 09:05:34 +00:00
|
|
|
virtualModifierData->amd.object = ob->parent;
|
|
|
|
virtualModifierData->amd.modifier.next = md;
|
|
|
|
virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
|
|
|
|
md = &virtualModifierData->amd.modifier;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
else if (ob->parent->type == OB_CURVE && ob->partype == PARSKEL) {
|
2013-08-19 09:05:34 +00:00
|
|
|
virtualModifierData->cmd.object = ob->parent;
|
|
|
|
virtualModifierData->cmd.defaxis = ob->trackflag + 1;
|
|
|
|
virtualModifierData->cmd.modifier.next = md;
|
|
|
|
md = &virtualModifierData->cmd.modifier;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
|
2013-08-19 09:05:34 +00:00
|
|
|
virtualModifierData->lmd.object = ob->parent;
|
|
|
|
virtualModifierData->lmd.modifier.next = md;
|
|
|
|
md = &virtualModifierData->lmd.modifier;
|
2005-08-11 03:31:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-22 16:35:51 +00:00
|
|
|
/* shape key modifier, not yet for curves */
|
2012-09-19 10:12:07 +00:00
|
|
|
if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) {
|
2012-03-24 06:18:31 +00:00
|
|
|
if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
|
2013-08-19 09:05:34 +00:00
|
|
|
virtualModifierData->smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage;
|
2009-10-22 16:35:51 +00:00
|
|
|
else
|
2013-08-19 09:05:34 +00:00
|
|
|
virtualModifierData->smd.modifier.mode &= ~eModifierMode_Editmode | eModifierMode_OnCage;
|
2009-10-22 16:35:51 +00:00
|
|
|
|
2013-08-19 09:05:34 +00:00
|
|
|
virtualModifierData->smd.modifier.next = md;
|
|
|
|
md = &virtualModifierData->smd.modifier;
|
2009-10-22 16:35:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return md;
|
2005-08-11 03:31:33 +00:00
|
|
|
}
|
2012-10-15 03:16:38 +00:00
|
|
|
|
|
|
|
/* Takes an object and returns its first selected armature, else just its armature
|
2006-08-28 01:12:36 +00:00
|
|
|
* This should work for multiple armatures per object
|
|
|
|
*/
|
2005-09-07 18:07:24 +00:00
|
|
|
Object *modifiers_isDeformedByArmature(Object *ob)
|
2005-08-22 20:24:59 +00:00
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
2012-05-06 17:22:54 +00:00
|
|
|
ArmatureModifierData *amd = NULL;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2012-03-03 20:19:11 +00:00
|
|
|
/* return the first selected armature, this lets us use multiple armatures */
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (md->type == eModifierType_Armature) {
|
|
|
|
amd = (ArmatureModifierData *) md;
|
2006-05-29 13:59:18 +00:00
|
|
|
if (amd->object && (amd->object->flag & SELECT))
|
2006-05-14 12:45:13 +00:00
|
|
|
return amd->object;
|
2005-08-22 20:24:59 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2006-05-14 12:45:13 +00:00
|
|
|
if (amd) /* if were still here then return the last armature */
|
|
|
|
return amd->object;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2005-09-07 18:07:24 +00:00
|
|
|
return NULL;
|
New: CrazySpace [tm] correction
When Modifiers are used in Edit Mode to show the deformed result for
editing, all actual coordinates Blender works with are still the ones from
the original Cage. You can notice that with the Transform Widget or
helper lines while transforming.
Even worse, the actual transformations still happened on the original Cage
as well, making it very hard to edit. That caused the feature to be named
"CrazySpace" (baptized by Andy, afaik?).
This commit calculates the deformation transformation per vertex, and
inverse corrects it, so it's more intuitive editing this way.
Unfortunately all the deformation features of Blender don't use matrices
for defining deform, so the existing code cannot be re-used to retrieve
the correct deformation matrix per vertex. The solution I found is based
on calculating per face the transformation based on its first 3 vertices,
and store this transformation averaged in the face's vertices.
The solution can also only work on entire faces, because the full deform
can only be retrieved using 3 vertices. (using 2 vertices will miss edge-
aligned rotation, using 1 vertex can only retrieve translation).
By deriving the deformations per face, small errors will still happen,
especially on very low-poly Meshes with extreme deformations.
The only alternative I know now, is providing each vertex in
a mesh with 2 extreme small tangent vectors, which get deformed using the
existing code as well. That will mess up the existing deformation code too
much though, this solution has the benefit it works with each deform we can
up with later too.
Last note about CrazySpace: it can only be used to tweak Meshes. Do not
even try to add vertices, extrude, or duplicate. Probably we should disable
this... but preventing user errors isn't always power-user-friendly, eh. :)
2005-10-26 09:56:52 +00:00
|
|
|
}
|
|
|
|
|
2018-05-11 08:16:41 +02:00
|
|
|
Object *modifiers_isDeformedByMeshDeform(Object *ob)
|
|
|
|
{
|
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
|
|
|
MeshDeformModifierData *mdmd = NULL;
|
|
|
|
|
|
|
|
/* return the first selected armature, this lets us use multiple armatures */
|
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (md->type == eModifierType_MeshDeform) {
|
|
|
|
mdmd = (MeshDeformModifierData *) md;
|
|
|
|
if (mdmd->object && (mdmd->object->flag & SELECT))
|
|
|
|
return mdmd->object;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mdmd) /* if were still here then return the last armature */
|
|
|
|
return mdmd->object;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-10-15 03:16:38 +00:00
|
|
|
/* Takes an object and returns its first selected lattice, else just its lattice
|
|
|
|
* This should work for multiple lattices per object
|
2012-03-03 20:19:11 +00:00
|
|
|
*/
|
2006-12-23 11:56:22 +00:00
|
|
|
Object *modifiers_isDeformedByLattice(Object *ob)
|
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
2012-05-06 17:22:54 +00:00
|
|
|
LatticeModifierData *lmd = NULL;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2012-03-03 20:19:11 +00:00
|
|
|
/* return the first selected lattice, this lets us use multiple lattices */
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (md->type == eModifierType_Lattice) {
|
|
|
|
lmd = (LatticeModifierData *) md;
|
2006-12-23 11:56:22 +00:00
|
|
|
if (lmd->object && (lmd->object->flag & SELECT))
|
|
|
|
return lmd->object;
|
|
|
|
}
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2006-12-23 11:56:22 +00:00
|
|
|
if (lmd) /* if were still here then return the last lattice */
|
|
|
|
return lmd->object;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2006-12-23 11:56:22 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-10-15 03:16:38 +00:00
|
|
|
/* Takes an object and returns its first selected curve, else just its curve
|
|
|
|
* This should work for multiple curves per object
|
|
|
|
*/
|
|
|
|
Object *modifiers_isDeformedByCurve(Object *ob)
|
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
2012-10-15 03:16:38 +00:00
|
|
|
CurveModifierData *cmd = NULL;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2012-10-15 03:16:38 +00:00
|
|
|
/* return the first selected curve, this lets us use multiple curves */
|
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (md->type == eModifierType_Curve) {
|
|
|
|
cmd = (CurveModifierData *) md;
|
|
|
|
if (cmd->object && (cmd->object->flag & SELECT))
|
|
|
|
return cmd->object;
|
|
|
|
}
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2012-10-15 03:16:38 +00:00
|
|
|
if (cmd) /* if were still here then return the last curve */
|
|
|
|
return cmd->object;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2012-10-15 03:16:38 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2006-12-23 11:56:22 +00:00
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifiers_usesArmature(Object *ob, bArmature *arm)
|
2006-05-04 00:59:02 +00:00
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
2006-05-04 00:59:02 +00:00
|
|
|
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (md->type == eModifierType_Armature) {
|
|
|
|
ArmatureModifierData *amd = (ArmatureModifierData *) md;
|
|
|
|
if (amd->object && amd->object->data == arm)
|
2013-06-02 03:59:19 +00:00
|
|
|
return true;
|
2006-05-04 00:59:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
return false;
|
2006-05-04 00:59:02 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifier_isCorrectableDeformed(ModifierData *md)
|
2007-07-28 21:04:30 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2018-09-19 16:59:05 +02:00
|
|
|
return mti->deformMatricesEM != NULL;
|
2007-07-28 21:04:30 +00:00
|
|
|
}
|
|
|
|
|
2018-04-05 18:20:27 +02:00
|
|
|
bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob)
|
New: CrazySpace [tm] correction
When Modifiers are used in Edit Mode to show the deformed result for
editing, all actual coordinates Blender works with are still the ones from
the original Cage. You can notice that with the Transform Widget or
helper lines while transforming.
Even worse, the actual transformations still happened on the original Cage
as well, making it very hard to edit. That caused the feature to be named
"CrazySpace" (baptized by Andy, afaik?).
This commit calculates the deformation transformation per vertex, and
inverse corrects it, so it's more intuitive editing this way.
Unfortunately all the deformation features of Blender don't use matrices
for defining deform, so the existing code cannot be re-used to retrieve
the correct deformation matrix per vertex. The solution I found is based
on calculating per face the transformation based on its first 3 vertices,
and store this transformation averaged in the face's vertices.
The solution can also only work on entire faces, because the full deform
can only be retrieved using 3 vertices. (using 2 vertices will miss edge-
aligned rotation, using 1 vertex can only retrieve translation).
By deriving the deformations per face, small errors will still happen,
especially on very low-poly Meshes with extreme deformations.
The only alternative I know now, is providing each vertex in
a mesh with 2 extreme small tangent vectors, which get deformed using the
existing code as well. That will mess up the existing deformation code too
much though, this solution has the benefit it works with each deform we can
up with later too.
Last note about CrazySpace: it can only be used to tweak Meshes. Do not
even try to add vertices, extrude, or duplicate. Probably we should disable
this... but preventing user errors isn't always power-user-friendly, eh. :)
2005-10-26 09:56:52 +00:00
|
|
|
{
|
2013-08-19 09:05:34 +00:00
|
|
|
VirtualModifierData virtualModifierData;
|
|
|
|
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
|
2013-09-24 00:56:47 +00:00
|
|
|
int required_mode = eModifierMode_Realtime;
|
|
|
|
|
2018-04-05 18:20:27 +02:00
|
|
|
if (ob->mode == OB_MODE_EDIT) {
|
2013-09-24 00:56:47 +00:00
|
|
|
required_mode |= eModifierMode_Editmode;
|
2018-02-06 19:34:36 +11:00
|
|
|
}
|
2012-05-06 17:22:54 +00:00
|
|
|
for (; md; md = md->next) {
|
2013-09-24 00:56:47 +00:00
|
|
|
if (!modifier_isEnabled(scene, md, required_mode)) {
|
2012-10-07 09:48:59 +00:00
|
|
|
/* pass */
|
|
|
|
}
|
|
|
|
else if (modifier_isCorrectableDeformed(md)) {
|
2013-06-02 03:59:19 +00:00
|
|
|
return true;
|
2012-10-07 09:48:59 +00:00
|
|
|
}
|
New: CrazySpace [tm] correction
When Modifiers are used in Edit Mode to show the deformed result for
editing, all actual coordinates Blender works with are still the ones from
the original Cage. You can notice that with the Transform Widget or
helper lines while transforming.
Even worse, the actual transformations still happened on the original Cage
as well, making it very hard to edit. That caused the feature to be named
"CrazySpace" (baptized by Andy, afaik?).
This commit calculates the deformation transformation per vertex, and
inverse corrects it, so it's more intuitive editing this way.
Unfortunately all the deformation features of Blender don't use matrices
for defining deform, so the existing code cannot be re-used to retrieve
the correct deformation matrix per vertex. The solution I found is based
on calculating per face the transformation based on its first 3 vertices,
and store this transformation averaged in the face's vertices.
The solution can also only work on entire faces, because the full deform
can only be retrieved using 3 vertices. (using 2 vertices will miss edge-
aligned rotation, using 1 vertex can only retrieve translation).
By deriving the deformations per face, small errors will still happen,
especially on very low-poly Meshes with extreme deformations.
The only alternative I know now, is providing each vertex in
a mesh with 2 extreme small tangent vectors, which get deformed using the
existing code as well. That will mess up the existing deformation code too
much though, this solution has the benefit it works with each deform we can
up with later too.
Last note about CrazySpace: it can only be used to tweak Meshes. Do not
even try to add vertices, extrude, or duplicate. Probably we should disable
this... but preventing user errors isn't always power-user-friendly, eh. :)
2005-10-26 09:56:52 +00:00
|
|
|
}
|
2013-06-02 03:59:19 +00:00
|
|
|
return false;
|
New: CrazySpace [tm] correction
When Modifiers are used in Edit Mode to show the deformed result for
editing, all actual coordinates Blender works with are still the ones from
the original Cage. You can notice that with the Transform Widget or
helper lines while transforming.
Even worse, the actual transformations still happened on the original Cage
as well, making it very hard to edit. That caused the feature to be named
"CrazySpace" (baptized by Andy, afaik?).
This commit calculates the deformation transformation per vertex, and
inverse corrects it, so it's more intuitive editing this way.
Unfortunately all the deformation features of Blender don't use matrices
for defining deform, so the existing code cannot be re-used to retrieve
the correct deformation matrix per vertex. The solution I found is based
on calculating per face the transformation based on its first 3 vertices,
and store this transformation averaged in the face's vertices.
The solution can also only work on entire faces, because the full deform
can only be retrieved using 3 vertices. (using 2 vertices will miss edge-
aligned rotation, using 1 vertex can only retrieve translation).
By deriving the deformations per face, small errors will still happen,
especially on very low-poly Meshes with extreme deformations.
The only alternative I know now, is providing each vertex in
a mesh with 2 extreme small tangent vectors, which get deformed using the
existing code as well. That will mess up the existing deformation code too
much though, this solution has the benefit it works with each deform we can
up with later too.
Last note about CrazySpace: it can only be used to tweak Meshes. Do not
even try to add vertices, extrude, or duplicate. Probably we should disable
this... but preventing user errors isn't always power-user-friendly, eh. :)
2005-10-26 09:56:52 +00:00
|
|
|
}
|
2007-11-04 22:00:24 +00:00
|
|
|
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
/* Check whether the given object has a modifier in its stack that uses WEIGHT_MCOL CD layer
|
|
|
|
* to preview something... Used by DynamicPaint and WeightVG currently. */
|
2013-06-02 03:59:19 +00:00
|
|
|
bool modifiers_isPreview(Object *ob)
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
{
|
|
|
|
ModifierData *md = ob->modifiers.first;
|
|
|
|
|
|
|
|
for (; md; md = md->next) {
|
|
|
|
if (modifier_isPreview(md))
|
2013-06-02 03:59:19 +00:00
|
|
|
return true;
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
}
|
|
|
|
|
2013-06-02 03:59:19 +00:00
|
|
|
return false;
|
Add weight preview to WeightVG modifiers, and first, simple/basic refactor of how modifiers can generate preview.
User side:
* Preview for DynamicPaint should keep the same behavior (for now). Weight preview should be somawhat quicker, though.
* Preview for WeightVG modifiers is only active in WeightPaint mode, and if the affected vgroup is the active one.
* Last active preview modifier in stack wins!
Note: that modifier preview topic is yet to be further refined, quite raw/incomplete for now.
Dev side:
* In draw code, renamed DRAW_DYNAMIC_PAINT_PREVIEW flag to DRAW_MODIFIERS_PREVIEW
* Removed use of MOD_DPAINT_PREVIEW_READY in DynamicPaint code (seems unecessary, and if it was, should be of more general scope).
* Added eModifierTypeFlag_UsesPreview to ModifierTypeFlag, for modifiers that can generate some preview data.
* Added three new modifier funcs, to handle preview modifiers in draw code / mod stack.
* For weights preview: added the generic DM_update_weight_mcol func, which can update WEIGHT_MCOL layer with either a given array of weights (currently used by DynamicPaint only), or from current active vgroup(s).
So now, draw code is fully generic (i.e. no more modifier-type checking in it). Mod stack code is generic to some extent, but will need more work.
2012-01-22 17:54:23 +00:00
|
|
|
}
|
|
|
|
|
2007-12-17 11:47:24 +00:00
|
|
|
void modifier_freeTemporaryData(ModifierData *md)
|
|
|
|
{
|
2012-03-24 06:18:31 +00:00
|
|
|
if (md->type == eModifierType_Armature) {
|
2012-05-06 17:22:54 +00:00
|
|
|
ArmatureModifierData *amd = (ArmatureModifierData *)md;
|
2007-12-17 11:47:24 +00:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (amd->prevCos) {
|
2007-12-17 11:47:24 +00:00
|
|
|
MEM_freeN(amd->prevCos);
|
2012-05-06 17:22:54 +00:00
|
|
|
amd->prevCos = NULL;
|
2009-06-08 20:08:19 +00:00
|
|
|
}
|
2007-12-17 11:47:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-09 00:14:51 +00:00
|
|
|
/* ensure modifier correctness when changing ob->data */
|
|
|
|
void test_object_modifiers(Object *ob)
|
|
|
|
{
|
|
|
|
ModifierData *md;
|
|
|
|
|
|
|
|
/* just multires checked for now, since only multires
|
2012-03-03 20:19:11 +00:00
|
|
|
* modifies mesh data */
|
2010-09-09 00:14:51 +00:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (ob->type != OB_MESH) return;
|
2007-12-17 11:47:24 +00:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
for (md = ob->modifiers.first; md; md = md->next) {
|
|
|
|
if (md->type == eModifierType_Multires) {
|
2012-05-06 17:22:54 +00:00
|
|
|
MultiresModifierData *mmd = (MultiresModifierData *)md;
|
2008-09-24 11:52:31 +00:00
|
|
|
|
2010-09-09 00:14:51 +00:00
|
|
|
multiresModifier_set_levels_from_disps(mmd, ob);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-11-20 14:38:11 +00:00
|
|
|
|
2018-09-24 17:27:41 +02:00
|
|
|
/* where should this go?, it doesn't fit well anywhere :S - campbell */
|
2011-11-20 14:38:11 +00:00
|
|
|
|
|
|
|
/* elubie: changed this to default to the same dir as the render output
|
|
|
|
* to prevent saving to C:\ on Windows */
|
|
|
|
|
|
|
|
/* campbell: logic behind this...
|
|
|
|
*
|
|
|
|
* - if the ID is from a library, return library path
|
|
|
|
* - else if the file has been saved return the blend file path.
|
2012-03-18 07:38:51 +00:00
|
|
|
* - else if the file isn't saved and the ID isn't from a library, return the temp dir.
|
2011-11-20 14:38:11 +00:00
|
|
|
*/
|
2018-05-31 15:24:30 +02:00
|
|
|
const char *modifier_path_relbase(Main *bmain, Object *ob)
|
2011-11-20 14:38:11 +00:00
|
|
|
{
|
2017-11-06 17:17:10 +01:00
|
|
|
if (G.relbase_valid || ID_IS_LINKED(ob)) {
|
2018-05-31 15:24:30 +02:00
|
|
|
return ID_BLEND_PATH(bmain, &ob->id);
|
2011-11-20 14:38:11 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* last resort, better then using "" which resolves to the current
|
|
|
|
* working directory */
|
2014-11-23 15:54:29 +01:00
|
|
|
return BKE_tempdir_session();
|
2011-11-20 14:38:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-09 15:16:44 +02:00
|
|
|
const char *modifier_path_relbase_from_global(Object *ob)
|
|
|
|
{
|
|
|
|
if (G.relbase_valid || ID_IS_LINKED(ob)) {
|
|
|
|
return ID_BLEND_PATH_FROM_GLOBAL(&ob->id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* last resort, better then using "" which resolves to the current
|
|
|
|
* working directory */
|
|
|
|
return BKE_tempdir_session();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-20 14:38:11 +00:00
|
|
|
/* initializes the path with either */
|
|
|
|
void modifier_path_init(char *path, int path_maxlen, const char *name)
|
|
|
|
{
|
|
|
|
/* elubie: changed this to default to the same dir as the render output
|
|
|
|
* to prevent saving to C:\ on Windows */
|
|
|
|
BLI_join_dirfile(path, path_maxlen,
|
2014-11-23 15:54:29 +01:00
|
|
|
G.relbase_valid ? "//" : BKE_tempdir_session(),
|
2011-11-20 14:38:11 +00:00
|
|
|
name);
|
|
|
|
}
|
2013-06-19 08:00:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
|
|
|
|
|
2018-10-09 12:23:22 +11:00
|
|
|
struct DerivedMesh *modwrap_applyModifier_DM_deprecated(
|
2018-05-01 17:33:04 +02:00
|
|
|
ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct DerivedMesh *dm)
|
2013-06-19 08:00:20 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2013-06-19 08:00:20 +00:00
|
|
|
BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
|
|
|
|
|
|
|
|
if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
|
|
|
DM_ensure_normals(dm);
|
|
|
|
}
|
2018-05-01 17:33:04 +02:00
|
|
|
return modifier_applyModifier_DM_deprecated(md, ctx, dm);
|
2013-06-19 08:00:20 +00:00
|
|
|
}
|
|
|
|
|
2018-10-09 12:23:22 +11:00
|
|
|
struct DerivedMesh *modwrap_applyModifierEM_DM_deprecated(
|
2018-05-01 17:33:04 +02:00
|
|
|
ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct BMEditMesh *em, DerivedMesh *dm)
|
2013-06-19 08:00:20 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2013-06-19 08:00:20 +00:00
|
|
|
BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
|
|
|
|
|
|
|
|
if (mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
|
|
|
DM_ensure_normals(dm);
|
|
|
|
}
|
2018-05-01 17:33:04 +02:00
|
|
|
return modifier_applyModifierEM_DM_deprecated(md, ctx, em, dm);
|
2013-06-19 08:00:20 +00:00
|
|
|
}
|
|
|
|
|
2018-10-09 12:23:22 +11:00
|
|
|
void modwrap_deformVerts_DM_deprecated(
|
2018-05-01 17:33:04 +02:00
|
|
|
ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
DerivedMesh *dm, float (*vertexCos)[3], int numVerts)
|
2013-06-19 08:00:20 +00:00
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2013-06-19 08:00:20 +00:00
|
|
|
BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
|
|
|
|
|
|
|
|
if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
|
|
|
DM_ensure_normals(dm);
|
|
|
|
}
|
2018-05-01 17:33:04 +02:00
|
|
|
modifier_deformVerts_DM_deprecated(md, ctx, dm, vertexCos, numVerts);
|
2013-06-19 08:00:20 +00:00
|
|
|
}
|
|
|
|
|
2018-10-09 12:23:22 +11:00
|
|
|
void modwrap_deformVertsEM_DM_deprecated(
|
2018-05-01 17:33:04 +02:00
|
|
|
ModifierData *md, const ModifierEvalContext *ctx,
|
2013-06-19 08:00:20 +00:00
|
|
|
struct BMEditMesh *em, DerivedMesh *dm,
|
|
|
|
float (*vertexCos)[3], int numVerts)
|
|
|
|
{
|
2015-03-30 21:17:07 +11:00
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
2013-06-19 08:00:20 +00:00
|
|
|
BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false);
|
|
|
|
|
|
|
|
if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
|
|
|
|
DM_ensure_normals(dm);
|
|
|
|
}
|
2018-05-01 17:33:04 +02:00
|
|
|
modifier_deformVertsEM_DM_deprecated(md, ctx, em, dm, vertexCos, numVerts);
|
2013-06-19 08:00:20 +00:00
|
|
|
}
|
|
|
|
/* end modifier callback wrappers */
|
2018-04-18 15:45:54 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* wrappers for modifier callbacks that accept Mesh and select the proper implementation
|
|
|
|
* depending on if the modifier has been ported to Mesh or is still using DerivedMesh
|
|
|
|
*/
|
|
|
|
|
2018-04-24 04:08:16 -04:00
|
|
|
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);
|
|
|
|
}
|
2018-09-19 17:51:14 +02:00
|
|
|
mti->deformVerts(md, ctx, mesh, vertexCos, numVerts);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-04-24 04:08:16 -04:00
|
|
|
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);
|
|
|
|
}
|
2018-09-20 12:04:17 +02:00
|
|
|
return mti->applyModifier(md, ctx, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-24 18:46:51 +02:00
|
|
|
/* deprecated variants of above that accept DerivedMesh */
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
void modifier_deformVerts_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct DerivedMesh *dm,
|
|
|
|
float (*vertexCos)[3], int numVerts)
|
2018-04-18 15:45:54 +02:00
|
|
|
{
|
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
/* TODO(sybren): deduplicate all the copies of this code in this file. */
|
|
|
|
Mesh *mesh = NULL;
|
|
|
|
if (dm != NULL) {
|
|
|
|
mesh = BKE_id_new_nomain(ID_ME, NULL);
|
|
|
|
DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
mti->deformVerts(md, ctx, mesh, vertexCos, numVerts);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
if (mesh != NULL) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
void modifier_deformMatrices_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct DerivedMesh *dm,
|
2018-04-18 15:45:54 +02:00
|
|
|
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
|
|
|
|
{
|
|
|
|
|
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
/* TODO(sybren): deduplicate all the copies of this code in this file. */
|
|
|
|
Mesh *mesh = NULL;
|
|
|
|
if (dm != NULL) {
|
|
|
|
mesh = BKE_id_new_nomain(ID_ME, NULL);
|
|
|
|
DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
mti->deformMatrices(md, ctx, mesh, vertexCos, defMats, numVerts);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
if (mesh != NULL) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
void modifier_deformVertsEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct BMEditMesh *editData, struct DerivedMesh *dm,
|
2018-04-18 15:45:54 +02:00
|
|
|
float (*vertexCos)[3], int numVerts)
|
|
|
|
{
|
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
/* TODO(sybren): deduplicate all the copies of this code in this file. */
|
|
|
|
Mesh *mesh = NULL;
|
|
|
|
if (dm != NULL) {
|
|
|
|
mesh = BKE_id_new_nomain(ID_ME, NULL);
|
|
|
|
DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
mti->deformVertsEM(md, ctx, editData, mesh, vertexCos, numVerts);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
if (mesh != NULL) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
void modifier_deformMatricesEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct BMEditMesh *editData, struct DerivedMesh *dm,
|
2018-04-18 15:45:54 +02:00
|
|
|
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
|
|
|
|
{
|
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
/* TODO(sybren): deduplicate all the copies of this code in this file. */
|
|
|
|
Mesh *mesh = NULL;
|
|
|
|
if (dm != NULL) {
|
|
|
|
mesh = BKE_id_new_nomain(ID_ME, NULL);
|
|
|
|
DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
mti->deformMatricesEM(md, ctx, editData, mesh, vertexCos, defMats, numVerts);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-19 16:59:05 +02:00
|
|
|
if (mesh != NULL) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
struct DerivedMesh *modifier_applyModifier_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct DerivedMesh *dm)
|
2018-04-18 15:45:54 +02:00
|
|
|
{
|
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
/* TODO(sybren): deduplicate all the copies of this code in this file. */
|
|
|
|
Mesh *mesh = NULL;
|
|
|
|
if (dm != NULL) {
|
|
|
|
mesh = BKE_id_new_nomain(ID_ME, NULL);
|
|
|
|
DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
struct Mesh *new_mesh = mti->applyModifier(md, ctx, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
/* Make a DM that doesn't reference new_mesh so we can free the latter. */
|
|
|
|
DerivedMesh *ndm = CDDM_from_mesh_ex(new_mesh, CD_DUPLICATE, CD_MASK_EVERYTHING);
|
2018-04-19 11:03:58 +02:00
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
if (new_mesh != mesh) {
|
|
|
|
BKE_id_free(NULL, new_mesh);
|
|
|
|
}
|
|
|
|
if (mesh != NULL) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
2018-09-20 12:04:17 +02:00
|
|
|
|
|
|
|
return ndm;
|
|
|
|
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 17:33:04 +02:00
|
|
|
struct DerivedMesh *modifier_applyModifierEM_DM_deprecated(struct ModifierData *md, const ModifierEvalContext *ctx,
|
|
|
|
struct BMEditMesh *editData,
|
|
|
|
struct DerivedMesh *dm)
|
2018-04-18 15:45:54 +02:00
|
|
|
{
|
|
|
|
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
/* TODO(sybren): deduplicate all the copies of this code in this file. */
|
|
|
|
Mesh *mesh = NULL;
|
|
|
|
if (dm != NULL) {
|
|
|
|
mesh = BKE_id_new_nomain(ID_ME, NULL);
|
|
|
|
DM_to_mesh(dm, mesh, ctx->object, CD_MASK_EVERYTHING, false);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
struct Mesh *new_mesh = mti->applyModifierEM(md, ctx, editData, mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
/* Make a DM that doesn't reference new_mesh so we can free the latter. */
|
|
|
|
DerivedMesh *ndm = CDDM_from_mesh_ex(new_mesh, CD_DUPLICATE, CD_MASK_EVERYTHING);
|
2018-04-18 15:45:54 +02:00
|
|
|
|
2018-09-20 12:04:17 +02:00
|
|
|
if (new_mesh != mesh) {
|
|
|
|
BKE_id_free(NULL, new_mesh);
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
2018-09-20 12:04:17 +02:00
|
|
|
if (mesh != NULL) {
|
|
|
|
BKE_id_free(NULL, mesh);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ndm;
|
|
|
|
|
2018-04-18 15:45:54 +02:00
|
|
|
}
|
|
|
|
|
2018-05-30 11:34:08 +02:00
|
|
|
/**
|
|
|
|
* Get evaluated mesh for other evaluated object, which is used as an operand for the modifier,
|
|
|
|
* e.g. second operand for boolean modifier.
|
|
|
|
* Note thqt modifiers in stack always get fully evaluated COW ID pointers, never original ones. Makes things simpler.
|
2018-05-09 12:44:22 +02:00
|
|
|
*/
|
2018-05-30 11:34:08 +02:00
|
|
|
Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval, bool *r_free_mesh)
|
2018-05-09 12:44:22 +02:00
|
|
|
{
|
2018-05-30 11:34:08 +02:00
|
|
|
Mesh *me;
|
|
|
|
|
|
|
|
if ((ob_eval->type == OB_MESH) && (ob_eval->mode & OB_MODE_EDIT)) {
|
|
|
|
/* Note: currently we have no equivalent to derived cagemesh or even final dm in BMEditMesh...
|
|
|
|
* This is TODO in core depsgraph/modifier stack code still. */
|
|
|
|
BMEditMesh *em = BKE_editmesh_from_object(ob_eval);
|
|
|
|
me = BKE_bmesh_to_mesh_nomain(em->bm, &(struct BMeshToMeshParams){0});
|
|
|
|
*r_free_mesh = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
me = ob_eval->runtime.mesh_eval;
|
|
|
|
*r_free_mesh = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return me;
|
2018-05-09 12:44:22 +02:00
|
|
|
}
|