2
* $Id: editdeform.c 16366 2008-09-04 20:51:28Z blendix $
4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software Foundation,
18
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21
* All rights reserved.
23
* The Original Code is: all of this file.
25
* Contributor(s): none yet.
27
* ***** END GPL LICENSE BLOCK *****
28
* Creator-specific support for vertex deformation groups
29
* Added: apply deform function (ton)
34
#include "MEM_guardedalloc.h"
36
#include "DNA_cloth_types.h"
37
#include "DNA_curve_types.h"
38
#include "DNA_lattice_types.h"
39
#include "DNA_mesh_types.h"
40
#include "DNA_meshdata_types.h"
41
#include "DNA_modifier_types.h"
42
#include "DNA_object_types.h"
43
#include "DNA_object_force.h"
44
#include "DNA_particle_types.h"
46
#include "BLI_blenlib.h"
47
#include "BLI_editVert.h"
49
#include "BKE_customdata.h"
50
#include "BKE_DerivedMesh.h"
51
#include "BKE_depsgraph.h"
52
#include "BKE_deform.h"
53
#include "BKE_displist.h"
54
#include "BKE_global.h"
55
#include "BKE_lattice.h"
57
#include "BKE_utildefines.h"
59
#include "BIF_interface.h"
60
#include "BIF_editdeform.h"
61
#include "BIF_editmesh.h"
62
#include "BIF_space.h"
63
#include "BIF_toolbox.h"
76
/* only in editmode */
77
void sel_verts_defgroup (int select)
91
for (eve=G.editMesh->verts.first; eve; eve=eve->next){
92
dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
94
if (dvert && dvert->totweight){
95
for (i=0; i<dvert->totweight; i++){
96
if (dvert->dw[i].def_nr == (ob->actdef-1)){
97
if (select) eve->f |= SELECT;
98
else eve->f &= ~SELECT;
105
/* this has to be called, because this function operates on vertices only */
106
if(select) EM_select_flush(); // vertices to edges/faces
107
else EM_deselect_flush();
111
if(editLatt->dvert) {
115
dvert= editLatt->dvert;
117
tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
118
for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) {
119
for (i=0; i<dvert->totweight; i++){
120
if (dvert->dw[i].def_nr == (ob->actdef-1)) {
121
if(select) bp->f1 |= SELECT;
122
else bp->f1 &= ~SELECT;
139
/* check if deform vertex has defgroup index */
140
MDeformWeight *get_defweight (MDeformVert *dv, int defgroup)
144
if (!dv || defgroup<0)
147
for (i=0; i<dv->totweight; i++){
148
if (dv->dw[i].def_nr == defgroup)
154
/* Ensures that mv has a deform weight entry for
155
the specified defweight group */
156
/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
157
MDeformWeight *verify_defweight (MDeformVert *dv, int defgroup)
159
MDeformWeight *newdw;
161
/* do this check always, this function is used to check for it */
162
if (!dv || defgroup<0)
165
newdw = get_defweight (dv, defgroup);
169
newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight");
171
memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
176
dv->dw[dv->totweight].weight=0.0f;
177
dv->dw[dv->totweight].def_nr=defgroup;
182
return dv->dw+(dv->totweight-1);
185
void add_defgroup (Object *ob)
187
add_defgroup_name (ob, "Group");
190
bDeformGroup *add_defgroup_name (Object *ob, char *name)
192
bDeformGroup *defgroup;
197
defgroup = MEM_callocN (sizeof(bDeformGroup), "add deformGroup");
199
BLI_strncpy (defgroup->name, name, 32);
201
BLI_addtail(&ob->defbase, defgroup);
202
unique_vertexgroup_name(defgroup, ob);
204
ob->actdef = BLI_countlist(&ob->defbase);
209
void duplicate_defgroup ( Object *ob )
211
bDeformGroup *dg, *cdg;
212
char name[32], s[32];
213
MDeformWeight *org, *cpy;
218
if (ob->type != OB_MESH)
221
dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
225
if (strstr(dg->name, "_copy")) {
226
BLI_strncpy (name, dg->name, 32); /* will be renamed _copy.001... etc */
228
BLI_snprintf (name, 32, "%s_copy", dg->name);
229
while (get_named_vertexgroup (ob, name)) {
230
if ((strlen (name) + 6) > 32) {
231
error ("Error: the name for the new group is > 32 characters");
235
BLI_snprintf (name, 32, "%s_copy", s);
239
cdg = copy_defgroup (dg);
240
strcpy (cdg->name, name);
241
unique_vertexgroup_name(cdg, ob);
243
BLI_addtail (&ob->defbase, cdg);
245
idg = (ob->actdef-1);
246
ob->actdef = BLI_countlist (&ob->defbase);
247
icdg = (ob->actdef-1);
253
for (i = 0; i < me->totvert; i++) {
255
org = get_defweight (dvert, idg);
257
cpy = verify_defweight (dvert, icdg);
258
cpy->weight = org->weight;
263
static void del_defgroup_update_users(Object *ob, int id)
265
ExplodeModifierData *emd;
267
ParticleSystem *psys;
268
ClothModifierData *clmd;
269
ClothSimSettings *clsim;
272
/* these cases don't use names to refer to vertex groups, so when
273
* they get deleted the numbers get out of sync, this corrects that */
276
if(ob->soft->vertgroup == id)
277
ob->soft->vertgroup= 0;
278
else if(ob->soft->vertgroup > id)
279
ob->soft->vertgroup--;
282
for(md=ob->modifiers.first; md; md=md->next) {
283
if(md->type == eModifierType_Explode) {
284
emd= (ExplodeModifierData*)md;
286
if(emd->vgroup == id)
288
else if(emd->vgroup > id)
291
else if(md->type == eModifierType_Cloth) {
292
clmd= (ClothModifierData*)md;
293
clsim= clmd->sim_parms;
296
if(clsim->vgroup_mass == id)
297
clsim->vgroup_mass= 0;
298
else if(clsim->vgroup_mass > id)
299
clsim->vgroup_mass--;
301
if(clsim->vgroup_bend == id)
302
clsim->vgroup_bend= 0;
303
else if(clsim->vgroup_bend > id)
304
clsim->vgroup_bend--;
306
if(clsim->vgroup_struct == id)
307
clsim->vgroup_struct= 0;
308
else if(clsim->vgroup_struct > id)
309
clsim->vgroup_struct--;
314
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
315
for(a=0; a<PSYS_TOT_VG; a++)
316
if(psys->vgroup[a] == id)
318
else if(psys->vgroup[a] > id)
323
void del_defgroup_in_object_mode ( Object *ob )
330
if ((!ob) || (ob->type != OB_MESH))
333
dg = BLI_findlink (&ob->defbase, (ob->actdef-1));
339
for (i = 0; i < me->totvert; i++) {
340
dvert = me->dvert + i;
342
if (get_defweight (dvert, (ob->actdef-1)))
343
remove_vert_defgroup (ob, dg, i);
347
for (i = 0; i < me->totvert; i++) {
350
for (e = 0; e < dvert->totweight; e++) {
351
if (dvert->dw[e].def_nr > (ob->actdef-1))
352
dvert->dw[e].def_nr--;
358
del_defgroup_update_users(ob, ob->actdef);
360
/* Update the active deform index if necessary */
361
if (ob->actdef == BLI_countlist(&ob->defbase))
364
/* Remove the group */
365
BLI_freelinkN (&ob->defbase, dg);
368
void del_defgroup (Object *ob)
370
bDeformGroup *defgroup;
379
defgroup = BLI_findlink(&ob->defbase, ob->actdef-1);
383
/* Make sure that no verts are using this group */
384
remove_verts_defgroup(1);
386
/* Make sure that any verts with higher indices are adjusted accordingly */
387
if(ob->type==OB_MESH) {
388
EditMesh *em = G.editMesh;
392
for (eve=em->verts.first; eve; eve=eve->next){
393
dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
396
for (i=0; i<dvert->totweight; i++)
397
if (dvert->dw[i].def_nr > (ob->actdef-1))
398
dvert->dw[i].def_nr--;
403
MDeformVert *dvert= editLatt->dvert;
407
tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
408
for(a=0, bp= editLatt->def; a<tot; a++, bp++, dvert++) {
409
for (i=0; i<dvert->totweight; i++){
410
if (dvert->dw[i].def_nr > (ob->actdef-1))
411
dvert->dw[i].def_nr--;
417
del_defgroup_update_users(ob, ob->actdef);
419
/* Update the active deform index if necessary */
420
if (ob->actdef==BLI_countlist(&ob->defbase))
423
/* Remove the group */
424
BLI_freelinkN (&ob->defbase, defgroup);
426
/* remove all dverts */
428
if(ob->type==OB_MESH) {
430
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
434
if (editLatt->dvert) {
435
MEM_freeN(editLatt->dvert);
436
editLatt->dvert= NULL;
442
void create_dverts(ID *id)
444
/* create deform verts
447
if( GS(id->name)==ID_ME) {
448
Mesh *me= (Mesh *)id;
449
me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
451
else if( GS(id->name)==ID_LT) {
452
Lattice *lt= (Lattice *)id;
453
lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert");
457
/* for mesh in object mode
458
lattice can be in editmode */
459
void remove_vert_def_nr (Object *ob, int def_nr, int vertnum)
461
/* This routine removes the vertex from the deform
462
* group with number def_nr.
464
* This routine is meant to be fast, so it is the
465
* responsibility of the calling routine to:
466
* a) test whether ob is non-NULL
467
* b) test whether ob is a mesh
468
* c) calculate def_nr
471
MDeformWeight *newdw;
472
MDeformVert *dvert= NULL;
475
/* get the deform vertices corresponding to the
478
if(ob->type==OB_MESH) {
479
if( ((Mesh*)ob->data)->dvert )
480
dvert = ((Mesh*)ob->data)->dvert + vertnum;
482
else if(ob->type==OB_LATTICE) {
483
Lattice *lt= ob->data;
489
dvert = lt->dvert + vertnum;
495
/* for all of the deform weights in the
498
for (i=dvert->totweight - 1 ; i>=0 ; i--){
500
/* if the def_nr is the same as the one
501
* for our weight group then remove it
502
* from this deform vert.
504
if (dvert->dw[i].def_nr == def_nr) {
507
/* if there are still other deform weights
508
* attached to this vert then remove this
509
* deform weight, and reshuffle the others
511
if (dvert->totweight) {
512
newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight),
515
memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
516
memcpy (newdw+i, dvert->dw+i+1,
517
sizeof(MDeformWeight)*(dvert->totweight-i));
518
MEM_freeN (dvert->dw);
522
/* if there are no other deform weights
523
* left then just remove the deform weight
526
MEM_freeN (dvert->dw);
535
/* for Mesh in Object mode */
536
/* allows editmode for Lattice */
537
void add_vert_defnr (Object *ob, int def_nr, int vertnum,
538
float weight, int assignmode)
540
/* add the vert to the deform group with the
543
MDeformVert *dv= NULL;
544
MDeformWeight *newdw;
548
if(ob->type==OB_MESH) {
549
if(((Mesh*)ob->data)->dvert)
550
dv = ((Mesh*)ob->data)->dvert + vertnum;
552
else if(ob->type==OB_LATTICE) {
561
dv = lt->dvert + vertnum;
567
/* Lets first check to see if this vert is
568
* already in the weight group -- if so
571
for (i=0; i<dv->totweight; i++){
573
/* if this weight cooresponds to the
574
* deform group, then add it using
575
* the assign mode provided
577
if (dv->dw[i].def_nr == def_nr){
579
switch (assignmode) {
581
dv->dw[i].weight=weight;
584
dv->dw[i].weight+=weight;
585
if (dv->dw[i].weight >= 1.0)
586
dv->dw[i].weight = 1.0;
588
case WEIGHT_SUBTRACT:
589
dv->dw[i].weight-=weight;
590
/* if the weight is zero or less then
591
* remove the vert from the deform group
593
if (dv->dw[i].weight <= 0.0)
594
remove_vert_def_nr(ob, def_nr, vertnum);
601
/* if the vert wasn't in the deform group then
602
* we must take a different form of action ...
605
switch (assignmode) {
606
case WEIGHT_SUBTRACT:
607
/* if we are subtracting then we don't
608
* need to do anything
614
/* if we are doing an additive assignment, then
615
* we need to create the deform weight
617
newdw = MEM_callocN (sizeof(MDeformWeight)*(dv->totweight+1),
620
memcpy (newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight);
625
dv->dw[dv->totweight].weight=weight;
626
dv->dw[dv->totweight].def_nr=def_nr;
633
/* called while not in editmode */
634
void add_vert_to_defgroup (Object *ob, bDeformGroup *dg, int vertnum,
635
float weight, int assignmode)
637
/* add the vert to the deform group with the
638
* specified assign mode
642
/* get the deform group number, exit if
645
def_nr = get_defgroup_num(ob, dg);
646
if (def_nr < 0) return;
648
/* if there's no deform verts then
651
if(ob->type==OB_MESH) {
652
if (!((Mesh*)ob->data)->dvert)
653
create_dverts(ob->data);
655
else if(ob->type==OB_LATTICE) {
656
if (!((Lattice*)ob->data)->dvert)
657
create_dverts(ob->data);
660
/* call another function to do the work
662
add_vert_defnr (ob, def_nr, vertnum, weight, assignmode);
665
/* Only available in editmode */
666
void assign_verts_defgroup (void)
668
extern float editbutvweight; /* buttons.c */
671
bDeformGroup *dg, *eg;
672
MDeformWeight *newdw;
676
if(multires_level1_test()) return;
683
dg=BLI_findlink(&ob->defbase, ob->actdef-1);
685
error ("No vertex group is active");
691
if (!CustomData_has_layer(&G.editMesh->vdata, CD_MDEFORMVERT))
692
EM_add_data_layer(&G.editMesh->vdata, CD_MDEFORMVERT);
694
/* Go through the list of editverts and assign them */
695
for (eve=G.editMesh->verts.first; eve; eve=eve->next){
696
dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
698
if (dvert && (eve->f & 1)){
700
/* See if this vert already has a reference to this group */
701
/* If so: Change its weight */
703
for (i=0; i<dvert->totweight; i++){
704
eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
705
/* Find the actual group */
707
dvert->dw[i].weight=editbutvweight;
712
/* If not: Add the group and set its weight */
714
newdw = MEM_callocN (sizeof(MDeformWeight)*(dvert->totweight+1), "deformWeight");
716
memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*dvert->totweight);
717
MEM_freeN (dvert->dw);
721
dvert->dw[dvert->totweight].weight= editbutvweight;
722
dvert->dw[dvert->totweight].def_nr= ob->actdef-1;
735
if(editLatt->dvert==NULL)
736
create_dverts(&editLatt->id);
738
tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
739
for(a=0, bp= editLatt->def; a<tot; a++, bp++) {
741
add_vert_defnr (ob, ob->actdef-1, a, editbutvweight, WEIGHT_REPLACE);
746
printf ("Assigning deformation groups to unknown object type\n");
752
/* mesh object mode, lattice can be in editmode */
753
void remove_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
755
/* This routine removes the vertex from the specified
761
/* if the object is NULL abort
766
/* get the deform number that cooresponds
767
* to this deform group, and abort if it
770
def_nr = get_defgroup_num(ob, dg);
771
if (def_nr < 0) return;
773
/* call another routine to do the work
775
remove_vert_def_nr (ob, def_nr, vertnum);
778
/* for mesh in object mode lattice can be in editmode */
779
static float get_vert_def_nr (Object *ob, int def_nr, int vertnum)
781
MDeformVert *dvert= NULL;
784
/* get the deform vertices corresponding to the
787
if(ob->type==OB_MESH) {
788
if( ((Mesh*)ob->data)->dvert )
789
dvert = ((Mesh*)ob->data)->dvert + vertnum;
791
else if(ob->type==OB_LATTICE) {
792
Lattice *lt= ob->data;
798
dvert = lt->dvert + vertnum;
804
for(i=dvert->totweight-1 ; i>=0 ; i--)
805
if(dvert->dw[i].def_nr == def_nr)
806
return dvert->dw[i].weight;
811
/* mesh object mode, lattice can be in editmode */
812
float get_vert_defgroup (Object *ob, bDeformGroup *dg, int vertnum)
819
def_nr = get_defgroup_num(ob, dg);
820
if(def_nr < 0) return 0.0f;
822
return get_vert_def_nr (ob, def_nr, vertnum);
825
/* Only available in editmode */
826
/* removes from active defgroup, if allverts==0 only selected vertices */
827
void remove_verts_defgroup (int allverts)
832
MDeformWeight *newdw;
833
bDeformGroup *dg, *eg;
836
if(multires_level1_test()) return;
843
dg=BLI_findlink(&ob->defbase, ob->actdef-1);
845
error ("No vertex group is active");
851
for (eve=G.editMesh->verts.first; eve; eve=eve->next){
852
dvert= CustomData_em_get(&G.editMesh->vdata, eve->data, CD_MDEFORMVERT);
854
if (dvert && dvert->dw && ((eve->f & 1) || allverts)){
855
for (i=0; i<dvert->totweight; i++){
857
eg = BLI_findlink (&ob->defbase, dvert->dw[i].def_nr);
860
if (dvert->totweight){
861
newdw = MEM_mallocN (sizeof(MDeformWeight)*(dvert->totweight), "deformWeight");
864
memcpy (newdw, dvert->dw, sizeof(MDeformWeight)*i);
865
memcpy (newdw+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
866
MEM_freeN (dvert->dw);
871
MEM_freeN (dvert->dw);
882
if(editLatt->dvert) {
884
int a, tot= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
886
for(a=0, bp= editLatt->def; a<tot; a++, bp++) {
887
if(allverts || (bp->f1 & SELECT))
888
remove_vert_defgroup (ob, dg, a);
894
printf ("Removing deformation groups from unknown object type\n");
899
/* Only available in editmode */
900
/* removes from all defgroup, if allverts==0 only selected vertices */
901
void remove_verts_defgroups(int allverts)
904
int actdef, defCount;
906
if (multires_level1_test()) return;
909
if (ob == NULL) return;
912
defCount= BLI_countlist(&ob->defbase);
915
error("Object has no vertex groups");
919
/* To prevent code redundancy, we just use remove_verts_defgroup, but that
920
* only operates on the active vgroup. So we iterate through all groups, by changing
923
for (ob->actdef= 1; ob->actdef <= defCount; ob->actdef++)
924
remove_verts_defgroup(allverts);
929
void vertexgroup_select_by_name(Object *ob, char *name)
931
bDeformGroup *curdef;
936
for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++){
937
if (!strcmp(curdef->name, name)) {
942
ob->actdef=0; // this signals on painting to create a new one, if a bone in posemode is selected */
945
/* This function provides a shortcut for adding/removing verts from
946
* vertex groups. It is called by the Ctrl-G hotkey in EditMode for Meshes
947
* and Lattices. (currently only restricted to those two)
948
* It is only responsible for
950
void vgroup_assign_with_menu(void)
952
Object *ob= G.obedit;
956
/* prevent crashes */
957
if (ob==NULL) return;
959
defCount= BLI_countlist(&ob->defbase);
961
/* give user choices of adding to current/new or removing from current */
962
if (defCount && ob->actdef)
963
mode = pupmenu("Vertex Groups %t|Add Selected to New Group %x1|Add Selected to Active Group %x2|Remove Selected from Active Group %x3|Remove Selected from All Groups %x4");
965
mode= pupmenu("Vertex Groups %t|Add Selected to New Group %x1");
969
case 1: /* add to new group */
971
assign_verts_defgroup();
972
allqueue(REDRAWVIEW3D, 1);
973
BIF_undo_push("Assign to vertex group");
975
case 2: /* add to current group */
976
assign_verts_defgroup();
977
allqueue(REDRAWVIEW3D, 1);
978
BIF_undo_push("Assign to vertex group");
980
case 3: /* remove from current group */
981
remove_verts_defgroup(0);
982
allqueue(REDRAWVIEW3D, 1);
983
BIF_undo_push("Remove from vertex group");
985
case 4: /* remove from all groups */
986
remove_verts_defgroups(0);
987
allqueue(REDRAWVIEW3D, 1);
988
BIF_undo_push("Remove from all vertex groups");
993
/* This function provides a shortcut for commonly used vertex group
994
* functions - change weight (not implemented), change active group, delete active group,
995
* when Ctrl-Shift-G is used in EditMode, for Meshes and Lattices (only for now).
997
void vgroup_operation_with_menu(void)
999
Object *ob= G.obedit;
1003
/* prevent crashes and useless cases */
1004
if (ob==NULL) return;
1006
defCount= BLI_countlist(&ob->defbase);
1007
if (defCount == 0) return;
1009
/* give user choices of adding to current/new or removing from current */
1011
mode = pupmenu("Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2");
1013
mode= pupmenu("Vertex Groups %t|Change Active Group%x1");
1015
/* handle choices */
1017
case 1: /* change active group*/
1019
char *menustr= get_vertexgroup_menustr(ob);
1023
nr= pupmenu(menustr);
1025
if ((nr >= 1) && (nr <= defCount))
1030
allqueue(REDRAWBUTSALL, 0);
1033
case 2: /* delete active group */
1036
allqueue (REDRAWVIEW3D, 1);
1037
allqueue(REDRAWOOPS, 0);
1038
BIF_undo_push("Delete vertex group");
1044
/* ******************* other deform edit stuff ********** */
1046
void object_apply_deform(Object *ob)
1048
notice("Apply Deformation now only availble in Modifier buttons");