Todo issue: sculpting on deformed mesh

Used a crazyspace approach (like in edit mode), but only modifiers with
deformMatricies are allowed atm (currently shapekeys and armature modifiers only).
All the rest modifiers had an warning message that they aren't applied because
of sculpt mode. Deformation of multires is also unsupported.

With all this restictions users will always see the actual "layer" (or maybe
mesh state would be more correct word) they are sculpting on.

Internal changes:
- All modifiers could have deformMatricies callback (the same as deformMatriciesEM but
  for non-edit mode usage)
- Added function to build crazyspace for sculpting (sculpt_get_deform_matrices), but it
  could be generalized for usage in other painting modes (particle edit mode, i.e)

Todo:
- Implement crazyspace correction to support all kinds of deformation modifiers
- Maybe deformation of multires isn't so difficult?
- And maybe we could avoid extra bad-level-stub for ED_sculpt_modifiers_changed
  without code duplicating?
This commit is contained in:
Sergey Sharybin 2011-01-31 20:02:51 +00:00
parent 55865239a2
commit 329e2d8037
53 changed files with 408 additions and 143 deletions

View File

@ -508,6 +508,10 @@ void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em
int editmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct EditMesh *em,
float (**deformmats)[3][3], float (**deformcos)[3]);
/* returns an array of deform matrices for crazyspace correction when sculpting */
void sculpt_get_deform_matrices(struct Scene *scene, struct Object *ob,
float (**deformmats)[3][3], float (**deformcos)[3]);
void weight_to_rgb(float input, float *fr, float *fg, float *fb);
/* convert layers requested by a GLSL material to actually available layers in

View File

@ -134,6 +134,12 @@ typedef struct ModifierTypeInfo {
float (*vertexCos)[3], int numVerts,
int useRenderParams, int isFinalCalc);
/* Like deformMatricesEM but called from object mode (for supporting modifiers in sculpt mode) */
void (*deformMatrices)(
struct ModifierData *md, struct Object *ob,
struct DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
/* Like deformVerts but called during editmode (for supporting modifiers)
*/
void (*deformVertsEM)(

View File

@ -53,6 +53,7 @@ struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*
struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene,
struct ModifierData *lastmd);
struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, int use_first);
struct DerivedMesh *get_multires_dm(struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *ob);
void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction);

View File

@ -78,8 +78,11 @@ typedef struct SculptSession {
/* PBVH acceleration structure */
struct PBVH *pbvh;
/* Used temporarily per-stroke */
float *vertexcosnos;
/* Paiting on deformed mesh */
int modifiers_active; /* object is deformed with some modifiers */
float (*orig_cos)[3]; /* coords of undeformed mesh */
float (*deform_cos)[3]; /* coords of deformed mesh but without stroke displacement */
float (*deform_imats)[3][3]; /* crazyspace deformation matricies */
/* Partial redraw */
int partial_redraw;
@ -95,8 +98,6 @@ typedef struct SculptSession {
struct GPUDrawObject *drawobject;
int modifiers_active;
rcti previous_r;
} SculptSession;

View File

@ -72,7 +72,6 @@ typedef struct CCGDerivedMesh {
char *faceFlags;
struct PBVH *pbvh;
int pbvh_draw;
struct ListBase *fmap;
struct IndexNode *fmap_mem;

View File

@ -53,6 +53,7 @@
#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_texture.h"
#include "BKE_multires.h"
#include "BLO_sys_types.h" // for intptr_t support
@ -65,6 +66,8 @@
#include "GPU_extensions.h"
#include "GPU_material.h"
#include "ED_sculpt.h" /* for ED_sculpt_modifiers_changed */
///////////////////////////////////
///////////////////////////////////
@ -1676,6 +1679,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
int required_mode;
int isPrevDeform= FALSE;
int skipVirtualArmature = (useDeform < 0);
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
int has_multires = mmd != NULL, multires_applied = 0;
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
if(mmd && !mmd->sculptlvl)
has_multires = 0;
if(!skipVirtualArmature) {
firstmd = modifiers_getVirtualModifierList(ob);
@ -1714,6 +1723,12 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
if(mti->type == eModifierTypeType_OnlyDeform) {
if(sculpt_mode && !has_multires)
if(!ELEM(md->type, eModifierType_Armature, eModifierType_ShapeKey)) {
modifier_setError(md, "Not supported in sculpt mode.");
continue;
}
if(!deformedVerts)
deformedVerts = mesh_getVertexCos(me, &numVerts);
@ -1759,13 +1774,18 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
md->scene= scene;
if(!modifier_isEnabled(scene, md, required_mode)) continue;
if(mti->type == eModifierTypeType_OnlyDeform && !useDeform) continue;
if((mti->flags & eModifierTypeFlag_RequiresOriginalData) && dm) {
modifier_setError(md, "Modifier requires original data, bad stack position.");
continue;
}
if(sculpt_mode && (!has_multires || multires_applied))
if(md->type != eModifierType_Armature || multires_applied) {
modifier_setError(md, "Not supported in sculpt mode.");
continue;
}
if(needMapping && !modifier_supportsMapping(md)) continue;
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
@ -1928,6 +1948,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
/* grab modifiers until index i */
if((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
break;
if(sculpt_mode && md->type == eModifierType_Multires)
multires_applied = 1;
}
for(md=firstmd; md; md=md->next)
@ -2222,14 +2245,9 @@ static void clear_mesh_caches(Object *ob)
ob->derivedDeform->release(ob->derivedDeform);
ob->derivedDeform= NULL;
}
/* we free pbvh on changes, except during sculpt since it can't deal with
changing PVBH node organization, we hope topology does not change in
the meantime .. weak */
if(ob->sculpt && ob->sculpt->pbvh) {
if(!ob->sculpt->cache) {
BLI_pbvh_free(ob->sculpt->pbvh);
ob->sculpt->pbvh= NULL;
}
if(ob->sculpt) {
ED_sculpt_modifiers_changed(ob);
}
}
@ -2523,6 +2541,51 @@ int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, f
return numleft;
}
void sculpt_get_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
ModifierData *md;
DerivedMesh *dm;
int a, numVerts= 0;
float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
int has_multires = mmd != NULL && mmd->sculptlvl > 0;
if(has_multires) {
*deformmats= NULL;
*deformcos= NULL;
return;
}
dm= NULL;
md= modifiers_getVirtualModifierList(ob);
for(; md; md= md->next) {
ModifierTypeInfo *mti= modifierType_getInfo(md->type);
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatrices) {
if(!defmats) {
Mesh *me= (Mesh*)ob->data;
dm= getMeshDerivedMesh(me, ob, NULL);
deformedVerts= mesh_getVertexCos(me, &numVerts);
defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
for(a=0; a<numVerts; a++)
unit_m3(defmats[a]);
}
mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
}
}
if(dm)
dm->release(dm);
*deformmats= defmats;
*deformcos= deformedVerts;
}
/* ******************* GLSL ******************** */
void DM_add_tangent_layer(DerivedMesh *dm)

View File

@ -76,6 +76,7 @@ typedef struct {
/* Cached */
struct PBVH *pbvh;
int pbvh_draw;
/* Mesh connectivity */
struct ListBase *fmap;
struct IndexNode *fmap_mem;
@ -222,6 +223,17 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
cddm->pbvh_draw = can_pbvh_draw(ob, dm);
BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert);
if(ob->sculpt->modifiers_active) {
float (*vertCos)[3];
int totvert;
totvert= dm->getNumVerts(dm);
vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
dm->getVertCos(dm, vertCos);
BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos);
}
}
return cddm->pbvh;

View File

@ -92,8 +92,10 @@ MultiresModifierData *find_multires_modifier_before(Scene *scene, ModifierData *
return NULL;
}
/* used for applying scale on mdisps layer and syncing subdivide levels when joining objects */
static MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob)
/* used for applying scale on mdisps layer and syncing subdivide levels when joining objects
use_first - return first multires modifier if all multires'es are disabled
*/
MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob, int use_first)
{
ModifierData *md;
MultiresModifierData *mmd= NULL, *firstmmd= NULL;
@ -111,7 +113,7 @@ static MultiresModifierData *get_multires_modifier(Scene *scene, Object *ob)
}
}
if(!mmd) {
if(!mmd && use_first) {
/* active multires have not been found
try to use first one */
return firstmmd;
@ -1568,8 +1570,8 @@ void multires_load_old(Object *ob, Mesh *me)
static void multires_sync_levels(Scene *scene, Object *ob, Object *to_ob)
{
MultiresModifierData *mmd= get_multires_modifier(scene, ob);
MultiresModifierData *to_mmd= get_multires_modifier(scene, to_ob);
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 1);
MultiresModifierData *to_mmd= get_multires_modifier(scene, to_ob, 1);
if(!mmd) {
/* object could have MDISP even when there is no multires modifier
@ -1599,7 +1601,7 @@ void multires_apply_smat(Scene *scene, Object *ob, float smat[3][3])
int *gridOffset;
int i, /*numGrids,*/ gridSize, dGridSize, dSkip, totvert;
float (*vertCos)[3] = NULL;
MultiresModifierData *mmd= get_multires_modifier(scene, ob);
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 1);
MultiresModifierData high_mmd;
CustomData_external_read(&me->fdata, &me->id, CD_MASK_MDISPS, me->totface);
@ -1725,7 +1727,7 @@ void multires_topology_changed(Scene *scene, Object *ob)
Mesh *me= (Mesh*)ob->data;
MDisps *mdisp= NULL, *cur= NULL;
int i, grid= 0, corners;
MultiresModifierData *mmd= get_multires_modifier(scene, ob);
MultiresModifierData *mmd= get_multires_modifier(scene, ob, 1);
if(mmd)
multires_set_tot_mdisps(me, mmd->totlvl);

View File

@ -246,6 +246,13 @@ void free_sculptsession(Object *ob)
if(ss->layer_co)
MEM_freeN(ss->layer_co);
if(ss->orig_cos)
MEM_freeN(ss->orig_cos);
if(ss->deform_cos)
MEM_freeN(ss->deform_cos);
if(ss->deform_imats)
MEM_freeN(ss->deform_imats);
MEM_freeN(ss);
ob->sculpt = NULL;

View File

@ -70,8 +70,6 @@ static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v);
static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e);
static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f);
static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
///
static void *arena_alloc(CCGAllocatorHDL a, int numBytes) {
@ -1150,7 +1148,7 @@ static void ccgDM_drawVerts(DerivedMesh *dm) {
static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
{
if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
if(ccgdm->pbvh) {
CCGFace **faces;
int totface;
@ -2240,28 +2238,10 @@ static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
return ccgdm->fmap;
}
static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
{
ModifierData *md;
MultiresModifierData *mmd= ccgdm->multires.mmd;
/* in sync with sculpt mode, only use multires grid pbvh if we are
the last enabled modifier in the stack, otherwise we use the base
mesh */
if(!mmd)
return 0;
for(md=mmd->modifier.next; md; md= md->next)
if(modifier_isEnabled(mmd->modifier.scene, md, eModifierMode_Realtime))
return 0;
return 1;
}
static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
{
CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
int gridSize, numGrids, grid_pbvh;
int gridSize, numGrids;
if(!ob) {
ccgdm->pbvh= NULL;
@ -2271,21 +2251,8 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
if(!ob->sculpt)
return NULL;
grid_pbvh = ccgDM_use_grid_pbvh(ccgdm);
if(ob->sculpt->pbvh) {
if(grid_pbvh) {
/* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
but this can be freed on ccgdm release, this updates the pointers
when the ccgdm gets remade, the assumption is that the topology
does not change. */
ccgdm_create_grids(dm);
BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
}
if(ob->sculpt->pbvh)
ccgdm->pbvh = ob->sculpt->pbvh;
ccgdm->pbvh_draw = grid_pbvh;
}
if(ccgdm->pbvh)
return ccgdm->pbvh;
@ -2293,25 +2260,14 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
/* no pbvh exists yet, we need to create one. only in case of multires
we build a pbvh over the modified mesh, in other cases the base mesh
is being sculpted, so we build a pbvh from that. */
if(grid_pbvh) {
ccgdm_create_grids(dm);
ccgdm_create_grids(dm);
gridSize = ccgDM_getGridSize(dm);
numGrids = ccgDM_getNumGrids(dm);
gridSize = ccgDM_getGridSize(dm);
numGrids = ccgDM_getNumGrids(dm);
ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
numGrids, gridSize, (void**)ccgdm->gridFaces);
ccgdm->pbvh_draw = 1;
}
else if(ob->type == OB_MESH) {
Mesh *me= ob->data;
ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
me->totface, me->totvert);
ccgdm->pbvh_draw = 0;
}
ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
numGrids, gridSize, (void**)ccgdm->gridFaces);
return ccgdm->pbvh;
}

View File

@ -118,8 +118,6 @@ float BLI_pbvh_node_get_tmin(PBVHNode* node);
void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
void BLI_pbvh_redraw_BB(PBVH *bvh, float bb_min[3], float bb_max[3]);
void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *totface);
void BLI_pbvh_grids_update(PBVH *bvh, struct DMGridData **grids,
struct DMGridAdjacency *gridadj, void **gridfaces);
/* vertex deformer */
float (*BLI_pbvh_get_vertCos(struct PBVH *pbvh))[3];

View File

@ -109,6 +109,20 @@ void copy_m4_m3(float m1[][4], float m2[][3]) /* no clear */
}
void swap_m3m3(float m1[][3], float m2[][3])
{
float t;
int i, j;
for(i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
t = m1[i][j];
m1[i][j] = m2[i][j];
m2[i][j] = t;
}
}
}
void swap_m4m4(float m1[][4], float m2[][4])
{
float t;

View File

@ -1475,13 +1475,6 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int smo
}
}
void BLI_pbvh_grids_update(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, void **gridfaces)
{
bvh->grids= grids;
bvh->gridadj= gridadj;
bvh->gridfaces= gridfaces;
}
float (*BLI_pbvh_get_vertCos(PBVH *pbvh))[3]
{
int a;
@ -1520,13 +1513,22 @@ void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
}
if (pbvh->verts) {
MVert *mvert= pbvh->verts;
/* copy new verts coords */
for (a= 0; a < pbvh->totvert; ++a) {
copy_v3_v3(pbvh->verts[a].co, vertCos[a]);
for (a= 0; a < pbvh->totvert; ++a, ++mvert) {
copy_v3_v3(mvert->co, vertCos[a]);
mvert->flag |= ME_VERT_PBVH_UPDATE;
}
/* coordinates are new -- normals should also be updated */
mesh_calc_normals(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
for (a= 0; a < pbvh->totnode; ++a)
BLI_pbvh_node_mark_update(&pbvh->nodes[a]);
BLI_pbvh_update(pbvh, PBVH_UpdateBB, NULL);
BLI_pbvh_update(pbvh, PBVH_UpdateOriginalBB, NULL);
}
}

View File

@ -40,6 +40,7 @@ void ED_operatortypes_sculpt(void);
void sculpt_get_redraw_planes(float planes[4][4], struct ARegion *ar,
struct RegionView3D *rv3d, struct Object *ob);
void ED_sculpt_force_update(struct bContext *C);
void ED_sculpt_modifiers_changed(struct Object *ob);
/* paint_ops.c */
void ED_operatortypes_paint(void);

View File

@ -58,6 +58,7 @@
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_lattice.h" /* for armature_deform_verts */
#include "BIF_glutil.h"
@ -91,12 +92,29 @@ void ED_sculpt_force_update(bContext *C)
multires_force_update(ob);
}
void ED_sculpt_modifiers_changed(Object *ob)
{
SculptSession *ss= ob->sculpt;
if(!ss->cache) {
/* we free pbvh on changes, except during sculpt since it can't deal with
changing PVBH node organization, we hope topology does not change in
the meantime .. weak */
if(ss->pbvh) {
BLI_pbvh_free(ss->pbvh);
ss->pbvh= NULL;
}
sculpt_free_deformMats(ob->sculpt);
}
}
/* Sculpt mode handles multires differently from regular meshes, but only if
it's the last modifier on the stack and it is not on the first level */
struct MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
{
Mesh *me= (Mesh*)ob->data;
ModifierData *md, *nmd;
ModifierData *md;
if(!CustomData_get_layer(&me->fdata, CD_MDISPS)) {
/* multires can't work without displacement layer */
@ -107,40 +125,52 @@ struct MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
if(md->type == eModifierType_Multires) {
MultiresModifierData *mmd= (MultiresModifierData*)md;
/* Check if any of the modifiers after multires are active
* if not it can use the multires struct */
for(nmd= md->next; nmd; nmd= nmd->next)
if(modifier_isEnabled(scene, nmd, eModifierMode_Realtime))
break;
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime))
continue;
if(!nmd && mmd->sculptlvl > 0)
return mmd;
if(mmd->sculptlvl > 0) return mmd;
else return NULL;
}
}
return NULL;
}
/* Checks whether full update mode (slower) needs to be used to work with modifiers */
/* Check if there are any active modifiers in stack (used for flushing updates at enter/exit sculpt mode) */
int sculpt_has_active_modifiers(Scene *scene, Object *ob)
{
ModifierData *md;
md= modifiers_getVirtualModifierList(ob);
/* exception for shape keys because we can edit those */
for(; md; md= md->next) {
if(modifier_isEnabled(scene, md, eModifierMode_Realtime))
return 1;
}
return 0;
}
/* Checks if there are any supported deformation modifiers active */
int sculpt_modifiers_active(Scene *scene, Object *ob)
{
ModifierData *md;
MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
/* check if there are any modifiers after what we are sculpting,
for a multires modifier with a deform modifier in front, we
do no need to recalculate the modifier stack. note that this
needs to be in sync with ccgDM_use_grid_pbvh! */
if(mmd)
md= mmd->modifier.next;
else
md= modifiers_getVirtualModifierList(ob);
if(mmd) return 0;
md= modifiers_getVirtualModifierList(ob);
/* exception for shape keys because we can edit those */
for(; md; md= md->next) {
if(modifier_isEnabled(scene, md, eModifierMode_Realtime))
if(md->type != eModifierType_ShapeKey)
return 1;
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
if(md->type==eModifierType_ShapeKey) continue;
if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatrices)
return 1;
}
return 0;
@ -890,7 +920,9 @@ static void neighbor_average(SculptSession *ss, float avg[3], const unsigned ver
/* Don't modify corner vertices */
if(ncount==1) {
copy_v3_v3(avg, ss->mvert[vert].co);
if(ss->deform_cos) copy_v3_v3(avg, ss->deform_cos[vert]);
else copy_v3_v3(avg, ss->mvert[vert].co);
return;
}
@ -906,7 +938,8 @@ static void neighbor_average(SculptSession *ss, float avg[3], const unsigned ver
for(i=0; i<(f->v4?4:3); ++i) {
if(i != skip && (ncount!=2 || BLI_countlist(&ss->fmap[(&f->v1)[i]]) <= 2)) {
add_v3_v3(avg, ss->mvert[(&f->v1)[i]].co);
if(ss->deform_cos) add_v3_v3(avg, ss->deform_cos[(&f->v1)[i]]);
else add_v3_v3(avg, ss->mvert[(&f->v1)[i]].co);
++total;
}
}
@ -916,8 +949,10 @@ static void neighbor_average(SculptSession *ss, float avg[3], const unsigned ver
if(total>0)
mul_v3_fl(avg, 1.0f / total);
else
copy_v3_v3(avg, ss->mvert[vert].co);
else {
if(ss->deform_cos) copy_v3_v3(avg, ss->deform_cos[vert]);
else copy_v3_v3(avg, ss->mvert[vert].co);
}
}
static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, float bstrength)
@ -2198,9 +2233,8 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
ofs= key_to_vertcos(ob, kb);
/* calculate key coord offsets (from previous location) */
for (a= 0; a < me->totvert; a++) {
for (a= 0; a < me->totvert; a++)
VECSUB(ofs[a], vertCos[a], ofs[a]);
}
/* apply offsets on other keys */
currkey = me->key->block.first;
@ -2230,17 +2264,6 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
vertcos_to_key(ob, kb, vertCos);
}
/* copy the modified vertices from bvh to the active key */
static void sculpt_update_keyblock(SculptSession *ss)
{
float (*vertCos)[3]= BLI_pbvh_get_vertCos(ss->pbvh);
if (vertCos) {
sculpt_vertcos_to_key(ss->ob, ss->kb, vertCos);
MEM_freeN(vertCos);
}
}
static void do_brush_action(Sculpt *sd, SculptSession *ss, Brush *brush)
{
SculptSearchSphereData data;
@ -2326,15 +2349,6 @@ static void do_brush_action(Sculpt *sd, SculptSession *ss, Brush *brush)
}
}
/* copy the modified vertices from mesh to the active key */
if(ss->kb)
mesh_to_key(ss->ob->data, ss->kb);
/* optimization: we could avoid copying new coords to keyblock at each */
/* stroke step if there are no modifiers due to pbvh is used for displaying */
/* so to increase speed we'll copy new coords to keyblock when stroke is done */
if(ss->kb && ss->modifiers_active) sculpt_update_keyblock(ss);
MEM_freeN(nodes);
}
}
@ -2388,6 +2402,59 @@ static void sculpt_combine_proxies(Sculpt *sd, SculptSession *ss)
MEM_freeN(nodes);
}
/* copy the modified vertices from bvh to the active key */
static void sculpt_update_keyblock(SculptSession *ss)
{
float (*vertCos)[3];
/* Keyblock update happens after hadning deformation caused by modifiers,
so ss->orig_cos would be updated with new stroke */
if(ss->orig_cos) vertCos = ss->orig_cos;
else vertCos = BLI_pbvh_get_vertCos(ss->pbvh);
if (vertCos) {
sculpt_vertcos_to_key(ss->ob, ss->kb, vertCos);
if(vertCos != ss->orig_cos)
MEM_freeN(vertCos);
}
}
/* flush displacement from deformed PBVH to original layer */
static void sculpt_flush_deformation(SculptSession *ss)
{
float (*vertCos)[3];
vertCos= BLI_pbvh_get_vertCos(ss->pbvh);
if (vertCos) {
Object *ob= ss->ob;
Mesh *me= (Mesh*)ob->data;
MVert *mvert= me->mvert;
int a;
for(a = 0; a < me->totvert; ++a, ++mvert) {
float disp[3], newco[3];
sub_v3_v3v3(disp, vertCos[a], ss->deform_cos[a]);
mul_m3_v3(ss->deform_imats[a], disp);
add_v3_v3v3(newco, disp, ss->orig_cos[a]);
copy_v3_v3(ss->deform_cos[a], vertCos[a]);
copy_v3_v3(ss->orig_cos[a], newco);
if(!ss->kb)
copy_v3_v3(mvert->co, newco);
}
if(ss->kb)
sculpt_update_keyblock(ss);
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
MEM_freeN(vertCos);
}
}
//static int max_overlap_count(Sculpt *sd)
//{
// int count[3];
@ -2496,6 +2563,9 @@ static void do_symmetrical_brush_actions(Sculpt *sd, SculptSession *ss)
/* hack to fix noise texture tearing mesh */
sculpt_fix_noise_tear(sd, ss);
if (ss->modifiers_active)
sculpt_flush_deformation(ss);
cache->first_time= 0;
}
@ -2517,6 +2587,17 @@ static void sculpt_update_tex(Sculpt *sd, SculptSession *ss)
}
}
void sculpt_free_deformMats(SculptSession *ss)
{
if(ss->orig_cos) MEM_freeN(ss->orig_cos);
if(ss->deform_cos) MEM_freeN(ss->deform_cos);
if(ss->deform_imats) MEM_freeN(ss->deform_imats);
ss->orig_cos = NULL;
ss->deform_cos = NULL;
ss->deform_imats = NULL;
}
void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap)
{
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
@ -2551,6 +2632,23 @@ void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap)
ss->pbvh = dm->getPBVH(ob, dm);
ss->fmap = (need_fmap && dm->getFaceMap)? dm->getFaceMap(ob, dm): NULL;
if(ss->modifiers_active) {
if(!ss->orig_cos) {
int a;
sculpt_free_deformMats(ss);
if(ss->kb) ss->orig_cos = key_to_vertcos(ob, ss->kb);
else ss->orig_cos = mesh_getVertexCos(ob->data, NULL);
sculpt_get_deform_matrices(scene, ob, &ss->deform_imats, &ss->deform_cos);
BLI_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
for(a = 0; a < ((Mesh*)ob->data)->totvert; ++a)
invert_m3(ss->deform_imats[a]);
}
} else sculpt_free_deformMats(ss);
/* if pbvh is deformed, key block is already applied to it */
if (ss->kb && !BLI_pbvh_isDeformed(ss->pbvh)) {
float (*vertCos)[3]= key_to_vertcos(ob, ss->kb);
@ -2792,8 +2890,12 @@ static void sculpt_update_cache_invariants(bContext* C, Sculpt *sd, SculptSessio
ss->layer_co= MEM_mallocN(sizeof(float) * 3 * ss->totvert,
"sculpt mesh vertices copy");
for(i = 0; i < ss->totvert; ++i)
copy_v3_v3(ss->layer_co[i], ss->mvert[i].co);
if(ss->deform_cos) memcpy(ss->layer_co, ss->deform_cos, ss->totvert);
else {
for(i = 0; i < ss->totvert; ++i) {
copy_v3_v3(ss->layer_co[i], ss->mvert[i].co);
}
}
}
}
@ -3214,7 +3316,6 @@ static void sculpt_flush_update(bContext *C)
rcti r;
BLI_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
if (sculpt_get_redraw_rect(ar, CTX_wm_region_view3d(C), ob, &r)) {
//rcti tmp;
@ -3489,7 +3590,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *unused)
/* multires in sculpt mode could have different from object mode subdivision level */
flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
/* if object has got active modifiers, it's dm could be different in sculpt mode */
//flush_recalc |= sculpt_modifiers_active(scene, ob);
flush_recalc |= sculpt_has_active_modifiers(scene, ob);
if(ob->mode & OB_MODE_SCULPT) {
if(mmd)
@ -3554,4 +3655,3 @@ void ED_operatortypes_sculpt(void)
WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
WM_operatortype_append(SCULPT_OT_set_persistent_base);
}

View File

@ -61,6 +61,9 @@ void sculpt(Sculpt *sd);
int sculpt_poll(struct bContext *C);
void sculpt_update_mesh_elements(struct Scene *scene, struct Object *ob, int need_fmap);
/* Deformed mesh sculpt */
void sculpt_free_deformMats(struct SculptSession *ss);
/* Stroke */
struct SculptStroke *sculpt_stroke_new(const int max);
void sculpt_stroke_free(struct SculptStroke *);
@ -78,6 +81,7 @@ typedef struct SculptUndoNode {
void *node; /* only during push, not valid afterwards! */
float (*co)[3];
float (*orig_co)[3];
short (*no)[3];
int totvert;

View File

@ -67,6 +67,12 @@ static void update_cb(PBVHNode *node, void *unused)
BLI_pbvh_node_mark_update(node);
}
static void sculpt_restore_deformed(SculptSession *ss, SculptUndoNode *unode, int uindex, int oindex, float coord[3])
{
swap_v3_v3(coord, unode->orig_co[uindex]);
copy_v3_v3(unode->co[uindex], ss->deform_cos[oindex]);
}
static void sculpt_undo_restore(bContext *C, ListBase *lb)
{
Scene *scene = CTX_data_scene(C);
@ -117,8 +123,10 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
float (*vertCos)[3];
vertCos= key_to_vertcos(ob, ss->kb);
for(i=0; i<unode->totvert; i++)
swap_v3_v3(vertCos[index[i]], unode->co[i]);
for(i=0; i<unode->totvert; i++) {
if(ss->modifiers_active) sculpt_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
else swap_v3_v3(vertCos[index[i]], unode->co[i]);
}
/* propagate new coords to keyblock */
sculpt_vertcos_to_key(ob, ss->kb, vertCos);
@ -130,7 +138,8 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
MEM_freeN(vertCos);
} else {
for(i=0; i<unode->totvert; i++) {
swap_v3_v3(mvert[index[i]].co, unode->co[i]);
if(ss->modifiers_active) sculpt_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
else swap_v3_v3(mvert[index[i]].co, unode->co[i]);
mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE;
}
}
@ -162,6 +171,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
}
if(update) {
int tag_update= 0;
/* we update all nodes still, should be more clever, but also
needs to work correct when exiting/entering sculpt mode and
the nodes get recreated, though in that case it could do all */
@ -171,7 +181,14 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
if((mmd=sculpt_multires_active(scene, ob)))
multires_mark_as_modified(ob);
if(ss->modifiers_active || ((Mesh*)ob->data)->id.us > 1)
tag_update= ((Mesh*)ob->data)->id.us > 1;
if(ss->modifiers_active) {
sculpt_free_deformMats(ss);
tag_update|= 1;
}
if(tag_update)
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
/* for non-PBVH drawing, need to recreate VBOs */
@ -194,6 +211,8 @@ static void sculpt_undo_free(ListBase *lb)
MEM_freeN(unode->grids);
if(unode->layer_disp)
MEM_freeN(unode->layer_disp);
if(unode->orig_co)
MEM_freeN(unode->orig_co);
}
}
@ -255,6 +274,9 @@ SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node)
unode->index= MEM_mapallocN(sizeof(int)*allvert, "SculptUndoNode.index");
}
if(ss->modifiers_active)
unode->orig_co= MEM_callocN(allvert*sizeof(*unode->orig_co), "undoSculpt orig_cos");
BLI_unlock_thread(LOCK_CUSTOM1);
/* copy threaded, hopefully this is the performance critical part */
@ -266,6 +288,9 @@ SculptUndoNode *sculpt_undo_push_node(SculptSession *ss, PBVHNode *node)
if(vd.no) VECCOPY(unode->no[vd.i], vd.no)
else normal_float_to_short_v3(unode->no[vd.i], vd.fno);
if(vd.vert_indices) unode->index[vd.i]= vd.vert_indices[vd.i];
if(ss->modifiers_active)
copy_v3_v3(unode->orig_co[vd.i], ss->orig_cos[unode->index[vd.i]]);
}
BLI_pbvh_vertex_iter_end;
}

View File

@ -34,6 +34,7 @@
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
#include "BLI_utildefines.h"
@ -161,6 +162,19 @@ static void deformMatricesEM(
if(!derivedData) dm->release(dm);
}
static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
{
ArmatureModifierData *amd = (ArmatureModifierData*) md;
DerivedMesh *dm = derivedData;
if(!derivedData) dm = CDDM_from_mesh((Mesh*)ob->data, ob);
armature_deform_verts(amd->object, ob, dm, vertexCos, defMats, numVerts,
amd->deformflag, NULL, amd->defgrp_name);
if(!derivedData) dm->release(dm);
}
ModifierTypeInfo modifierType_Armature = {
/* name */ "Armature",
@ -172,6 +186,7 @@ ModifierTypeInfo modifierType_Armature = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ deformMatrices,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ deformMatricesEM,
/* applyModifier */ 0,

View File

@ -807,6 +807,7 @@ ModifierTypeInfo modifierType_Array = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -129,6 +129,7 @@ ModifierTypeInfo modifierType_Bevel = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -139,6 +139,7 @@ ModifierTypeInfo modifierType_Boolean = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -287,6 +287,7 @@ ModifierTypeInfo modifierType_Build = {
| eModifierTypeFlag_AcceptsCVs,
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -619,6 +619,7 @@ ModifierTypeInfo modifierType_Cast = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -196,6 +196,7 @@ ModifierTypeInfo modifierType_Cloth = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -243,6 +243,7 @@ ModifierTypeInfo modifierType_Collision = {
/* copyData */ 0,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -142,6 +142,7 @@ ModifierTypeInfo modifierType_Curve = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -197,6 +197,7 @@ ModifierTypeInfo modifierType_Decimate = {
/* flags */ eModifierTypeFlag_AcceptsMesh,
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -357,6 +357,7 @@ ModifierTypeInfo modifierType_Displace = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -1278,6 +1278,7 @@ ModifierTypeInfo modifierType_EdgeSplit = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -895,6 +895,7 @@ ModifierTypeInfo modifierType_Explode = {
/* flags */ eModifierTypeFlag_AcceptsMesh,
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -142,6 +142,7 @@ ModifierTypeInfo modifierType_Fluidsim = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -284,6 +284,7 @@ ModifierTypeInfo modifierType_Hook = {
| eModifierTypeFlag_SupportsEditmode,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -137,6 +137,7 @@ ModifierTypeInfo modifierType_Lattice = {
| eModifierTypeFlag_SupportsEditmode,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -399,6 +399,7 @@ ModifierTypeInfo modifierType_Mask = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -445,6 +445,7 @@ ModifierTypeInfo modifierType_MeshDeform = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -338,6 +338,7 @@ ModifierTypeInfo modifierType_Mirror = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -109,6 +109,7 @@ ModifierTypeInfo modifierType_Multires = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -59,6 +59,7 @@ ModifierTypeInfo modifierType_None = {
/* copyData */ 0,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -330,6 +330,7 @@ ModifierTypeInfo modifierType_ParticleInstance = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -229,6 +229,7 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformVertsEM */ 0 /* deformVertsEM */ ,
/* deformMatrices */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,
/* applyModifierEM */ 0,

View File

@ -884,6 +884,7 @@ ModifierTypeInfo modifierType_Screw = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -64,6 +64,27 @@ static void deformVerts(ModifierData *md, Object *ob,
}
}
static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
{
Key *key= ob_get_key(ob);
KeyBlock *kb= ob_get_keyblock(ob);
float scale[3][3];
int a;
(void)vertexCos; /* unused */
if(kb && kb->totelem==numVerts && kb!=key->refkey) {
if(ob->shapeflag & OB_SHAPE_LOCK) scale_m3_fl(scale, 1);
else scale_m3_fl(scale, kb->curval);
for(a=0; a<numVerts; a++)
copy_m3_m3(defMats[a], scale);
}
deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
}
static void deformVertsEM(ModifierData *md, Object *ob,
struct EditMesh *UNUSED(editData),
DerivedMesh *derivedData,
@ -87,7 +108,7 @@ static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob,
KeyBlock *kb= ob_get_keyblock(ob);
float scale[3][3];
int a;
(void)vertexCos; /* unused */
if(kb && kb->totelem==numVerts && kb!=key->refkey) {
@ -98,7 +119,6 @@ static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob,
}
}
ModifierTypeInfo modifierType_ShapeKey = {
/* name */ "ShapeKey",
/* structName */ "ShapeKeyModifierData",
@ -109,6 +129,7 @@ ModifierTypeInfo modifierType_ShapeKey = {
/* copyData */ 0,
/* deformVerts */ deformVerts,
/* deformMatrices */ deformMatrices,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ deformMatricesEM,
/* applyModifier */ 0,

View File

@ -167,6 +167,7 @@ ModifierTypeInfo modifierType_Shrinkwrap = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -375,6 +375,7 @@ ModifierTypeInfo modifierType_SimpleDeform = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -154,6 +154,7 @@ ModifierTypeInfo modifierType_Smoke = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -256,6 +256,7 @@ ModifierTypeInfo modifierType_Smooth = {
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -68,6 +68,7 @@ ModifierTypeInfo modifierType_Softbody = {
/* copyData */ 0,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -651,6 +651,7 @@ ModifierTypeInfo modifierType_Solidify = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -133,6 +133,7 @@ ModifierTypeInfo modifierType_Subsurf = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -173,6 +173,7 @@ ModifierTypeInfo modifierType_Surface = {
/* copyData */ 0,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -413,6 +413,7 @@ ModifierTypeInfo modifierType_UVProject = {
/* copyData */ copyData,
/* deformVerts */ 0,
/* deformMatrices */ 0,
/* deformVertsEM */ 0,
/* deformMatricesEM */ 0,
/* applyModifier */ applyModifier,

View File

@ -452,6 +452,7 @@ ModifierTypeInfo modifierType_Wave = {
| eModifierTypeFlag_SupportsEditmode,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ 0,
/* deformVertsEM */ deformVertsEM,
/* deformMatricesEM */ 0,
/* applyModifier */ 0,

View File

@ -431,6 +431,7 @@ float sculpt_get_brush_unprojected_radius(struct Brush *brush){return 0.0f;}
void sculpt_set_brush_unprojected_radius(struct Brush *brush, float unprojected_radius){}
float sculpt_get_brush_alpha(struct Brush *brush){return 0.0f;}
void sculpt_set_brush_alpha(struct Brush *brush, float alpha){}
void ED_sculpt_modifiers_changed(struct Object *ob){};
char blender_path[] = "";