2002-10-12 11:37:38 +00:00
/**
* $ Id $
*
2008-04-16 22:40:48 +00:00
* * * * * * BEGIN GPL LICENSE BLOCK * * * * *
2002-10-12 11:37:38 +00:00
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
2008-04-16 22:40:48 +00:00
* of the License , or ( at your option ) any later version .
2002-10-12 11:37:38 +00:00
*
* 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 . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* The Original Code is Copyright ( C ) 2001 - 2002 by NaN Holding BV .
* All rights reserved .
*
* The Original Code is : all of this file .
*
* Contributor ( s ) : none yet .
*
2008-04-16 22:40:48 +00:00
* * * * * * END GPL LICENSE BLOCK * * * * *
2002-10-12 11:37:38 +00:00
* Creator - specific support for vertex deformation groups
2004-09-28 16:18:22 +00:00
* Added : apply deform function ( ton )
2002-10-12 11:37:38 +00:00
*/
# include <string.h>
# include "MEM_guardedalloc.h"
2008-05-10 12:33:15 +00:00
# include "DNA_cloth_types.h"
2004-09-28 16:18:22 +00:00
# include "DNA_curve_types.h"
2006-09-03 12:16:14 +00:00
# include "DNA_lattice_types.h"
2002-10-12 11:37:38 +00:00
# include "DNA_mesh_types.h"
2004-03-20 22:55:42 +00:00
# include "DNA_meshdata_types.h"
2008-05-10 12:33:15 +00:00
# include "DNA_modifier_types.h"
2002-10-12 11:37:38 +00:00
# include "DNA_object_types.h"
2008-05-10 12:33:15 +00:00
# include "DNA_object_force.h"
# include "DNA_particle_types.h"
2002-10-12 11:37:38 +00:00
Fix for undo... it didn't do the UV coords (tface) nor the vertexpaint
colors. This because of the pretty weird (ab)use of load & make editmesh...
For each added undo step, the load_editmesh was fed with an empty mesh
to assign data to, without knowledge of what was in the original mesh.
That way UV and color data got lost.
Solved it in 2 steps:
1. removing the ->tface pointer from EditVlak, and make TFace a builtin
struct inside EditVlak. This didnt cost much extra mem, since it already
stored UV and color. This enabled some pretty cleanup in editmesh.c as
well, storing tface pointers was cumbersome.
2. for each undo step, it then generates always a tface and mcol block to
link to the undo Mesh.
Even when it wasn't in the actual Mesh, at exit editmode the original
Mesh is used as reference anyway, and undo-meshes are freed correctly.
The enormous commit is because I had to change the BLI_editVert.h file, and
found it was included in about every file unnecessary. I removed it there.
ALso found out that subsurf has code ready (unfinished) to make UV coords for
the displaylist in EditMode as well, nice to know for later...
2003-11-19 22:00:14 +00:00
# include "BLI_blenlib.h"
# include "BLI_editVert.h"
2006-11-11 23:23:15 +00:00
# include "BKE_customdata.h"
2005-07-17 05:20:57 +00:00
# include "BKE_DerivedMesh.h"
# include "BKE_depsgraph.h"
2002-10-12 11:37:38 +00:00
# include "BKE_deform.h"
2004-09-28 16:18:22 +00:00
# include "BKE_displist.h"
2006-09-03 12:16:14 +00:00
# include "BKE_global.h"
# include "BKE_lattice.h"
2002-10-12 11:37:38 +00:00
# include "BKE_mesh.h"
2006-09-03 12:16:14 +00:00
# include "BKE_utildefines.h"
2002-10-12 11:37:38 +00:00
2007-05-30 10:36:17 +00:00
# include "BIF_interface.h"
2002-10-12 11:37:38 +00:00
# include "BIF_editdeform.h"
2004-10-11 18:35:42 +00:00
# include "BIF_editmesh.h"
2007-05-30 10:36:17 +00:00
# include "BIF_space.h"
2002-10-12 11:37:38 +00:00
# include "BIF_toolbox.h"
2004-01-10 20:52:59 +00:00
# include "BSE_edit.h"
2007-05-30 10:36:17 +00:00
# include "butspace.h"
# include "mydevice.h"
2007-01-04 22:16:49 +00:00
# include "editmesh.h"
2006-12-31 10:51:21 +00:00
# include "multires.h"
2002-11-25 12:02:15 +00:00
# ifdef HAVE_CONFIG_H
# include <config.h>
# endif
2006-09-03 12:16:14 +00:00
/* only in editmode */
2002-10-12 11:37:38 +00:00
void sel_verts_defgroup ( int select )
{
2006-09-03 12:16:14 +00:00
EditVert * eve ;
Object * ob ;
int i ;
2006-11-11 23:23:15 +00:00
MDeformVert * dvert ;
2002-10-12 11:37:38 +00:00
2006-09-03 12:16:14 +00:00
ob = G . obedit ;
2002-10-12 11:37:38 +00:00
if ( ! ob )
return ;
switch ( ob - > type ) {
case OB_MESH :
2006-09-03 12:16:14 +00:00
for ( eve = G . editMesh - > verts . first ; eve ; eve = eve - > next ) {
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
dvert = CustomData_em_get ( & G . editMesh - > vdata , eve - > data , CD_MDEFORMVERT ) ;
2006-11-11 23:23:15 +00:00
if ( dvert & & dvert - > totweight ) {
for ( i = 0 ; i < dvert - > totweight ; i + + ) {
if ( dvert - > dw [ i ] . def_nr = = ( ob - > actdef - 1 ) ) {
2004-10-11 18:35:42 +00:00
if ( select ) eve - > f | = SELECT ;
else eve - > f & = ~ SELECT ;
2004-11-05 10:19:13 +00:00
2002-10-12 11:37:38 +00:00
break ;
}
}
}
}
2006-09-03 12:16:14 +00:00
/* this has to be called, because this function operates on vertices only */
if ( select ) EM_select_flush ( ) ; // vertices to edges/faces
else EM_deselect_flush ( ) ;
2002-10-12 11:37:38 +00:00
break ;
2006-09-03 12:16:14 +00:00
case OB_LATTICE :
if ( editLatt - > dvert ) {
BPoint * bp ;
int a , tot ;
2006-11-11 23:23:15 +00:00
dvert = editLatt - > dvert ;
2006-09-03 12:16:14 +00:00
tot = editLatt - > pntsu * editLatt - > pntsv * editLatt - > pntsw ;
for ( a = 0 , bp = editLatt - > def ; a < tot ; a + + , bp + + , dvert + + ) {
for ( i = 0 ; i < dvert - > totweight ; i + + ) {
if ( dvert - > dw [ i ] . def_nr = = ( ob - > actdef - 1 ) ) {
if ( select ) bp - > f1 | = SELECT ;
else bp - > f1 & = ~ SELECT ;
break ;
}
}
}
}
break ;
2002-10-12 11:37:38 +00:00
default :
break ;
}
2006-09-03 12:16:14 +00:00
2004-01-10 20:52:59 +00:00
countall ( ) ;
2006-09-03 12:16:14 +00:00
2002-10-12 11:37:38 +00:00
}
2006-08-29 10:27:48 +00:00
/* check if deform vertex has defgroup index */
MDeformWeight * get_defweight ( MDeformVert * dv , int defgroup )
{
int i ;
if ( ! dv | | defgroup < 0 )
return NULL ;
for ( i = 0 ; i < dv - > totweight ; i + + ) {
if ( dv - > dw [ i ] . def_nr = = defgroup )
return dv - > dw + i ;
}
return NULL ;
}
2002-10-12 11:37:38 +00:00
/* Ensures that mv has a deform weight entry for
2005-10-25 13:57:37 +00:00
the specified defweight group */
/* Note this function is mirrored in editmesh_tools.c, for use for editvertices */
MDeformWeight * verify_defweight ( MDeformVert * dv , int defgroup )
2002-10-12 11:37:38 +00:00
{
MDeformWeight * newdw ;
2006-08-29 10:27:48 +00:00
/* do this check always, this function is used to check for it */
2005-09-07 18:07:24 +00:00
if ( ! dv | | defgroup < 0 )
2002-10-12 11:37:38 +00:00
return NULL ;
2006-08-29 10:27:48 +00:00
newdw = get_defweight ( dv , defgroup ) ;
if ( newdw )
return newdw ;
2002-10-12 11:37:38 +00:00
newdw = MEM_callocN ( sizeof ( MDeformWeight ) * ( dv - > totweight + 1 ) , " deformWeight " ) ;
if ( dv - > dw ) {
memcpy ( newdw , dv - > dw , sizeof ( MDeformWeight ) * dv - > totweight ) ;
MEM_freeN ( dv - > dw ) ;
}
dv - > dw = newdw ;
2006-09-03 12:16:14 +00:00
dv - > dw [ dv - > totweight ] . weight = 0.0f ;
2002-10-12 11:37:38 +00:00
dv - > dw [ dv - > totweight ] . def_nr = defgroup ;
/* Group index */
dv - > totweight + + ;
return dv - > dw + ( dv - > totweight - 1 ) ;
}
2005-10-25 13:57:37 +00:00
void add_defgroup ( Object * ob )
{
2003-04-24 00:48:43 +00:00
add_defgroup_name ( ob , " Group " ) ;
}
bDeformGroup * add_defgroup_name ( Object * ob , char * name )
2002-10-12 11:37:38 +00:00
{
bDeformGroup * defgroup ;
2003-04-24 00:48:43 +00:00
2002-10-12 11:37:38 +00:00
if ( ! ob )
2003-04-24 00:48:43 +00:00
return NULL ;
2005-10-20 20:38:08 +00:00
defgroup = MEM_callocN ( sizeof ( bDeformGroup ) , " add deformGroup " ) ;
2003-04-24 00:48:43 +00:00
2005-10-20 20:38:08 +00:00
BLI_strncpy ( defgroup - > name , name , 32 ) ;
2002-10-12 11:37:38 +00:00
BLI_addtail ( & ob - > defbase , defgroup ) ;
unique_vertexgroup_name ( defgroup , ob ) ;
ob - > actdef = BLI_countlist ( & ob - > defbase ) ;
2003-04-24 00:48:43 +00:00
return defgroup ;
2002-10-12 11:37:38 +00:00
}
2007-03-16 11:29:40 +00:00
void duplicate_defgroup ( Object * ob )
{
bDeformGroup * dg , * cdg ;
char name [ 32 ] , s [ 32 ] ;
MDeformWeight * org , * cpy ;
MDeformVert * dvert ;
Mesh * me ;
int i , idg , icdg ;
if ( ob - > type ! = OB_MESH )
return ;
dg = BLI_findlink ( & ob - > defbase , ( ob - > actdef - 1 ) ) ;
if ( ! dg )
return ;
2008-05-01 19:46:05 +00:00
if ( strstr ( dg - > name , " _copy " ) ) {
BLI_strncpy ( name , dg - > name , 32 ) ; /* will be renamed _copy.001... etc */
} else {
BLI_snprintf ( name , 32 , " %s_copy " , dg - > name ) ;
while ( get_named_vertexgroup ( ob , name ) ) {
if ( ( strlen ( name ) + 6 ) > 32 ) {
error ( " Error: the name for the new group is > 32 characters " ) ;
return ;
}
strcpy ( s , name ) ;
BLI_snprintf ( name , 32 , " %s_copy " , s ) ;
2007-03-16 11:29:40 +00:00
}
2008-05-01 19:46:05 +00:00
}
2007-03-16 11:29:40 +00:00
cdg = copy_defgroup ( dg ) ;
strcpy ( cdg - > name , name ) ;
2008-05-01 19:46:05 +00:00
unique_vertexgroup_name ( cdg , ob ) ;
2007-03-16 11:29:40 +00:00
BLI_addtail ( & ob - > defbase , cdg ) ;
idg = ( ob - > actdef - 1 ) ;
ob - > actdef = BLI_countlist ( & ob - > defbase ) ;
icdg = ( ob - > actdef - 1 ) ;
me = get_mesh ( ob ) ;
if ( ! me - > dvert )
return ;
for ( i = 0 ; i < me - > totvert ; i + + ) {
dvert = me - > dvert + i ;
org = get_defweight ( dvert , idg ) ;
if ( org ) {
cpy = verify_defweight ( dvert , icdg ) ;
cpy - > weight = org - > weight ;
}
}
}
2008-05-10 12:33:15 +00:00
static void del_defgroup_update_users ( Object * ob , int id )
{
ExplodeModifierData * emd ;
ModifierData * md ;
ParticleSystem * psys ;
ClothModifierData * clmd ;
ClothSimSettings * clsim ;
int a ;
/* these cases don't use names to refer to vertex groups, so when
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
* they get deleted the numbers get out of sync , this corrects that */
2008-05-10 12:33:15 +00:00
if ( ob - > soft ) {
if ( ob - > soft - > vertgroup = = id )
ob - > soft - > vertgroup = 0 ;
else if ( ob - > soft - > vertgroup > id )
ob - > soft - > vertgroup - - ;
}
for ( md = ob - > modifiers . first ; md ; md = md - > next ) {
if ( md - > type = = eModifierType_Explode ) {
emd = ( ExplodeModifierData * ) md ;
if ( emd - > vgroup = = id )
emd - > vgroup = 0 ;
else if ( emd - > vgroup > id )
emd - > vgroup - - ;
}
else if ( md - > type = = eModifierType_Cloth ) {
clmd = ( ClothModifierData * ) md ;
clsim = clmd - > sim_parms ;
if ( clsim ) {
if ( clsim - > vgroup_mass = = id )
clsim - > vgroup_mass = 0 ;
else if ( clsim - > vgroup_mass > id )
clsim - > vgroup_mass - - ;
if ( clsim - > vgroup_bend = = id )
clsim - > vgroup_bend = 0 ;
else if ( clsim - > vgroup_bend > id )
clsim - > vgroup_bend - - ;
if ( clsim - > vgroup_struct = = id )
clsim - > vgroup_struct = 0 ;
else if ( clsim - > vgroup_struct > id )
clsim - > vgroup_struct - - ;
}
}
}
for ( psys = ob - > particlesystem . first ; psys ; psys = psys - > next ) {
for ( a = 0 ; a < PSYS_TOT_VG ; a + + )
if ( psys - > vgroup [ a ] = = id )
psys - > vgroup [ a ] = 0 ;
else if ( psys - > vgroup [ a ] > id )
psys - > vgroup [ a ] - - ;
}
}
2007-03-16 11:29:40 +00:00
void del_defgroup_in_object_mode ( Object * ob )
{
bDeformGroup * dg ;
MDeformVert * dvert ;
Mesh * me ;
int i , e ;
if ( ( ! ob ) | | ( ob - > type ! = OB_MESH ) )
return ;
dg = BLI_findlink ( & ob - > defbase , ( ob - > actdef - 1 ) ) ;
if ( ! dg )
return ;
me = get_mesh ( ob ) ;
if ( me - > dvert ) {
for ( i = 0 ; i < me - > totvert ; i + + ) {
dvert = me - > dvert + i ;
if ( dvert ) {
if ( get_defweight ( dvert , ( ob - > actdef - 1 ) ) )
remove_vert_defgroup ( ob , dg , i ) ;
}
}
for ( i = 0 ; i < me - > totvert ; i + + ) {
dvert = me - > dvert + i ;
if ( dvert ) {
for ( e = 0 ; e < dvert - > totweight ; e + + ) {
if ( dvert - > dw [ e ] . def_nr > ( ob - > actdef - 1 ) )
dvert - > dw [ e ] . def_nr - - ;
}
}
}
}
2008-05-10 12:33:15 +00:00
del_defgroup_update_users ( ob , ob - > actdef ) ;
2007-03-16 11:29:40 +00:00
/* Update the active deform index if necessary */
if ( ob - > actdef = = BLI_countlist ( & ob - > defbase ) )
ob - > actdef - - ;
/* Remove the group */
BLI_freelinkN ( & ob - > defbase , dg ) ;
}
2002-10-12 11:37:38 +00:00
void del_defgroup ( Object * ob )
{
bDeformGroup * defgroup ;
int i ;
if ( ! ob )
return ;
if ( ! ob - > actdef )
return ;
defgroup = BLI_findlink ( & ob - > defbase , ob - > actdef - 1 ) ;
if ( ! defgroup )
return ;
/* Make sure that no verts are using this group */
remove_verts_defgroup ( 1 ) ;
/* Make sure that any verts with higher indices are adjusted accordingly */
2006-09-03 12:16:14 +00:00
if ( ob - > type = = OB_MESH ) {
EditMesh * em = G . editMesh ;
EditVert * eve ;
2006-11-11 23:23:15 +00:00
MDeformVert * dvert ;
2006-09-03 12:16:14 +00:00
for ( eve = em - > verts . first ; eve ; eve = eve - > next ) {
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
dvert = CustomData_em_get ( & G . editMesh - > vdata , eve - > data , CD_MDEFORMVERT ) ;
2006-11-11 23:23:15 +00:00
if ( dvert )
for ( i = 0 ; i < dvert - > totweight ; i + + )
if ( dvert - > dw [ i ] . def_nr > ( ob - > actdef - 1 ) )
dvert - > dw [ i ] . def_nr - - ;
2006-09-03 12:16:14 +00:00
}
}
else {
BPoint * bp ;
MDeformVert * dvert = editLatt - > dvert ;
int a , tot ;
2007-06-29 13:46:15 +00:00
if ( dvert ) {
tot = editLatt - > pntsu * editLatt - > pntsv * editLatt - > pntsw ;
for ( a = 0 , bp = editLatt - > def ; a < tot ; a + + , bp + + , dvert + + ) {
for ( i = 0 ; i < dvert - > totweight ; i + + ) {
if ( dvert - > dw [ i ] . def_nr > ( ob - > actdef - 1 ) )
dvert - > dw [ i ] . def_nr - - ;
}
2006-09-03 12:16:14 +00:00
}
2002-10-12 11:37:38 +00:00
}
}
2008-05-10 12:33:15 +00:00
del_defgroup_update_users ( ob , ob - > actdef ) ;
2006-09-03 12:16:14 +00:00
/* Update the active deform index if necessary */
2002-10-12 11:37:38 +00:00
if ( ob - > actdef = = BLI_countlist ( & ob - > defbase ) )
ob - > actdef - - ;
Armature "Envelope" editing.
For defining the deformation distances of Bones, three values are being
used now. The bone tip and root radius define the bone-shape itself and the
"dist" defines the soft area around it. A full (user) doc is in CMS here;
http://www.blender3d.org/cms/Armature_Envelopes.647.0.html
Note: todo still is allowing both Vertex Deform Groups and these Envelopes
together (and or per Bone).
Also part of this commit is:
- New: Hiding bones in EditMode. This is a separate 'hide flag', so you can
keep the PoseMode hidden Bones separate from EditMode.
(In the future we should do some kind of bone-grouping or so)
- While transform(), the hotkeys G,R,S only switch mode when the previous
mode was compatible. Caused conflicts with Crease/BoneDist/etc.
- Deleting the last VertexGroup now also deletes the entire Mesh 'dvert'
data. Sounds logical, but remember that VertexGroups are partial on a
Mesh, partial on Object. Weird design decision though...
Anyhoo, at this moment the only way to have Bone Envelopes deform, is
by deleting all VertexGroups!
- In PoseMode, the hotkey ALT+S now does both B-Bone size or Envelope,
depending draw type.
- In EditMode, Extrude now also works when only Root points were selected.
- Weight editing is also symmetrical btw, with the "X-axis Mirror" option
set.
2005-08-19 12:35:15 +00:00
2002-10-12 11:37:38 +00:00
/* Remove the group */
BLI_freelinkN ( & ob - > defbase , defgroup ) ;
Armature "Envelope" editing.
For defining the deformation distances of Bones, three values are being
used now. The bone tip and root radius define the bone-shape itself and the
"dist" defines the soft area around it. A full (user) doc is in CMS here;
http://www.blender3d.org/cms/Armature_Envelopes.647.0.html
Note: todo still is allowing both Vertex Deform Groups and these Envelopes
together (and or per Bone).
Also part of this commit is:
- New: Hiding bones in EditMode. This is a separate 'hide flag', so you can
keep the PoseMode hidden Bones separate from EditMode.
(In the future we should do some kind of bone-grouping or so)
- While transform(), the hotkeys G,R,S only switch mode when the previous
mode was compatible. Caused conflicts with Crease/BoneDist/etc.
- Deleting the last VertexGroup now also deletes the entire Mesh 'dvert'
data. Sounds logical, but remember that VertexGroups are partial on a
Mesh, partial on Object. Weird design decision though...
Anyhoo, at this moment the only way to have Bone Envelopes deform, is
by deleting all VertexGroups!
- In PoseMode, the hotkey ALT+S now does both B-Bone size or Envelope,
depending draw type.
- In EditMode, Extrude now also works when only Root points were selected.
- Weight editing is also symmetrical btw, with the "X-axis Mirror" option
set.
2005-08-19 12:35:15 +00:00
/* remove all dverts */
if ( ob - > actdef = = 0 ) {
2007-02-23 20:34:27 +00:00
if ( ob - > type = = OB_MESH ) {
Mesh * me = ob - > data ;
CustomData_free_layer_active ( & me - > vdata , CD_MDEFORMVERT , me - > totvert ) ;
me - > dvert = NULL ;
}
else {
if ( editLatt - > dvert ) {
MEM_freeN ( editLatt - > dvert ) ;
editLatt - > dvert = NULL ;
}
}
Armature "Envelope" editing.
For defining the deformation distances of Bones, three values are being
used now. The bone tip and root radius define the bone-shape itself and the
"dist" defines the soft area around it. A full (user) doc is in CMS here;
http://www.blender3d.org/cms/Armature_Envelopes.647.0.html
Note: todo still is allowing both Vertex Deform Groups and these Envelopes
together (and or per Bone).
Also part of this commit is:
- New: Hiding bones in EditMode. This is a separate 'hide flag', so you can
keep the PoseMode hidden Bones separate from EditMode.
(In the future we should do some kind of bone-grouping or so)
- While transform(), the hotkeys G,R,S only switch mode when the previous
mode was compatible. Caused conflicts with Crease/BoneDist/etc.
- Deleting the last VertexGroup now also deletes the entire Mesh 'dvert'
data. Sounds logical, but remember that VertexGroups are partial on a
Mesh, partial on Object. Weird design decision though...
Anyhoo, at this moment the only way to have Bone Envelopes deform, is
by deleting all VertexGroups!
- In PoseMode, the hotkey ALT+S now does both B-Bone size or Envelope,
depending draw type.
- In EditMode, Extrude now also works when only Root points were selected.
- Weight editing is also symmetrical btw, with the "X-axis Mirror" option
set.
2005-08-19 12:35:15 +00:00
}
2002-10-12 11:37:38 +00:00
}
2008-10-26 09:41:59 +00:00
void del_all_defgroups ( Object * ob )
{
/* Sanity check */
if ( ob = = NULL )
return ;
/* Remove all DVerts */
if ( ob - > type = = OB_MESH ) {
Mesh * me = ob - > data ;
CustomData_free_layer_active ( & me - > vdata , CD_MDEFORMVERT , me - > totvert ) ;
me - > dvert = NULL ;
}
else {
if ( editLatt - > dvert ) {
MEM_freeN ( editLatt - > dvert ) ;
editLatt - > dvert = NULL ;
}
}
/* Remove all DefGroups */
BLI_freelistN ( & ob - > defbase ) ;
/* Fix counters/indices */
ob - > actdef = 0 ;
}
2006-09-03 12:16:14 +00:00
void create_dverts ( ID * id )
2003-04-24 00:48:43 +00:00
{
2006-09-03 12:16:14 +00:00
/* create deform verts
2003-04-24 00:48:43 +00:00
*/
2006-09-03 12:16:14 +00:00
if ( GS ( id - > name ) = = ID_ME ) {
Mesh * me = ( Mesh * ) id ;
2006-12-12 21:29:09 +00:00
me - > dvert = CustomData_add_layer ( & me - > vdata , CD_MDEFORMVERT , CD_CALLOC , NULL , me - > totvert ) ;
2006-09-03 12:16:14 +00:00
}
else if ( GS ( id - > name ) = = ID_LT ) {
Lattice * lt = ( Lattice * ) id ;
lt - > dvert = MEM_callocN ( sizeof ( MDeformVert ) * lt - > pntsu * lt - > pntsv * lt - > pntsw , " lattice deformVert " ) ;
2003-04-24 00:48:43 +00:00
}
}
2006-09-03 12:16:14 +00:00
/* for mesh in object mode
lattice can be in editmode */
2003-04-24 00:48:43 +00:00
void remove_vert_def_nr ( Object * ob , int def_nr , int vertnum )
{
/* This routine removes the vertex from the deform
* group with number def_nr .
*
* This routine is meant to be fast , so it is the
* responsibility of the calling routine to :
* a ) test whether ob is non - NULL
* b ) test whether ob is a mesh
* c ) calculate def_nr
*/
MDeformWeight * newdw ;
2006-09-03 12:16:14 +00:00
MDeformVert * dvert = NULL ;
2003-04-24 00:48:43 +00:00
int i ;
2006-09-03 12:16:14 +00:00
/* get the deform vertices corresponding to the
2003-04-24 00:48:43 +00:00
* vertnum
*/
2006-09-03 12:16:14 +00:00
if ( ob - > type = = OB_MESH ) {
if ( ( ( Mesh * ) ob - > data ) - > dvert )
dvert = ( ( Mesh * ) ob - > data ) - > dvert + vertnum ;
}
else if ( ob - > type = = OB_LATTICE ) {
Lattice * lt = ob - > data ;
if ( ob = = G . obedit )
lt = editLatt ;
if ( lt - > dvert )
dvert = lt - > dvert + vertnum ;
}
2006-11-03 12:46:48 +00:00
if ( dvert = = NULL )
return ;
2003-04-24 00:48:43 +00:00
/* for all of the deform weights in the
* deform vert
*/
for ( i = dvert - > totweight - 1 ; i > = 0 ; i - - ) {
/* if the def_nr is the same as the one
* for our weight group then remove it
* from this deform vert .
*/
if ( dvert - > dw [ i ] . def_nr = = def_nr ) {
dvert - > totweight - - ;
/* if there are still other deform weights
* attached to this vert then remove this
* deform weight , and reshuffle the others
*/
if ( dvert - > totweight ) {
newdw = MEM_mallocN ( sizeof ( MDeformWeight ) * ( dvert - > totweight ) ,
" deformWeight " ) ;
if ( dvert - > dw ) {
memcpy ( newdw , dvert - > dw , sizeof ( MDeformWeight ) * i ) ;
memcpy ( newdw + i , dvert - > dw + i + 1 ,
sizeof ( MDeformWeight ) * ( dvert - > totweight - i ) ) ;
MEM_freeN ( dvert - > dw ) ;
}
dvert - > dw = newdw ;
}
/* if there are no other deform weights
* left then just remove the deform weight
*/
else {
MEM_freeN ( dvert - > dw ) ;
dvert - > dw = NULL ;
2006-12-01 19:52:04 +00:00
break ;
2003-04-24 00:48:43 +00:00
}
}
}
}
2006-09-03 12:16:14 +00:00
/* for Mesh in Object mode */
/* allows editmode for Lattice */
2003-04-24 00:48:43 +00:00
void add_vert_defnr ( Object * ob , int def_nr , int vertnum ,
float weight , int assignmode )
{
/* add the vert to the deform group with the
* specified number
*/
2006-09-03 12:16:14 +00:00
MDeformVert * dv = NULL ;
2003-04-24 00:48:43 +00:00
MDeformWeight * newdw ;
int i ;
2006-09-03 12:16:14 +00:00
/* get the vert */
if ( ob - > type = = OB_MESH ) {
if ( ( ( Mesh * ) ob - > data ) - > dvert )
dv = ( ( Mesh * ) ob - > data ) - > dvert + vertnum ;
}
else if ( ob - > type = = OB_LATTICE ) {
Lattice * lt ;
if ( ob = = G . obedit )
lt = editLatt ;
else
lt = ob - > data ;
if ( lt - > dvert )
dv = lt - > dvert + vertnum ;
}
if ( dv = = NULL )
Armature "Envelope" editing.
For defining the deformation distances of Bones, three values are being
used now. The bone tip and root radius define the bone-shape itself and the
"dist" defines the soft area around it. A full (user) doc is in CMS here;
http://www.blender3d.org/cms/Armature_Envelopes.647.0.html
Note: todo still is allowing both Vertex Deform Groups and these Envelopes
together (and or per Bone).
Also part of this commit is:
- New: Hiding bones in EditMode. This is a separate 'hide flag', so you can
keep the PoseMode hidden Bones separate from EditMode.
(In the future we should do some kind of bone-grouping or so)
- While transform(), the hotkeys G,R,S only switch mode when the previous
mode was compatible. Caused conflicts with Crease/BoneDist/etc.
- Deleting the last VertexGroup now also deletes the entire Mesh 'dvert'
data. Sounds logical, but remember that VertexGroups are partial on a
Mesh, partial on Object. Weird design decision though...
Anyhoo, at this moment the only way to have Bone Envelopes deform, is
by deleting all VertexGroups!
- In PoseMode, the hotkey ALT+S now does both B-Bone size or Envelope,
depending draw type.
- In EditMode, Extrude now also works when only Root points were selected.
- Weight editing is also symmetrical btw, with the "X-axis Mirror" option
set.
2005-08-19 12:35:15 +00:00
return ;
2003-04-24 00:48:43 +00:00
/* Lets first check to see if this vert is
* already in the weight group - - if so
* lets update it
*/
for ( i = 0 ; i < dv - > totweight ; i + + ) {
/* if this weight cooresponds to the
* deform group , then add it using
* the assign mode provided
*/
if ( dv - > dw [ i ] . def_nr = = def_nr ) {
switch ( assignmode ) {
case WEIGHT_REPLACE :
dv - > dw [ i ] . weight = weight ;
break ;
case WEIGHT_ADD :
dv - > dw [ i ] . weight + = weight ;
if ( dv - > dw [ i ] . weight > = 1.0 )
dv - > dw [ i ] . weight = 1.0 ;
break ;
case WEIGHT_SUBTRACT :
dv - > dw [ i ] . weight - = weight ;
/* if the weight is zero or less then
* remove the vert from the deform group
*/
if ( dv - > dw [ i ] . weight < = 0.0 )
remove_vert_def_nr ( ob , def_nr , vertnum ) ;
break ;
}
return ;
}
}
/* if the vert wasn't in the deform group then
* we must take a different form of action . . .
*/
switch ( assignmode ) {
case WEIGHT_SUBTRACT :
/* if we are subtracting then we don't
* need to do anything
*/
return ;
case WEIGHT_REPLACE :
case WEIGHT_ADD :
/* if we are doing an additive assignment, then
* we need to create the deform weight
*/
newdw = MEM_callocN ( sizeof ( MDeformWeight ) * ( dv - > totweight + 1 ) ,
" deformWeight " ) ;
if ( dv - > dw ) {
memcpy ( newdw , dv - > dw , sizeof ( MDeformWeight ) * dv - > totweight ) ;
MEM_freeN ( dv - > dw ) ;
}
dv - > dw = newdw ;
dv - > dw [ dv - > totweight ] . weight = weight ;
dv - > dw [ dv - > totweight ] . def_nr = def_nr ;
dv - > totweight + + ;
break ;
}
}
2006-09-03 12:16:14 +00:00
/* called while not in editmode */
2003-04-24 00:48:43 +00:00
void add_vert_to_defgroup ( Object * ob , bDeformGroup * dg , int vertnum ,
float weight , int assignmode )
{
/* add the vert to the deform group with the
* specified assign mode
*/
int def_nr ;
/* get the deform group number, exit if
* it can ' t be found
*/
def_nr = get_defgroup_num ( ob , dg ) ;
if ( def_nr < 0 ) return ;
2006-09-03 12:16:14 +00:00
/* if there's no deform verts then
2003-04-24 00:48:43 +00:00
* create some
*/
2006-09-03 12:16:14 +00:00
if ( ob - > type = = OB_MESH ) {
if ( ! ( ( Mesh * ) ob - > data ) - > dvert )
create_dverts ( ob - > data ) ;
}
else if ( ob - > type = = OB_LATTICE ) {
if ( ! ( ( Lattice * ) ob - > data ) - > dvert )
create_dverts ( ob - > data ) ;
2003-04-24 00:48:43 +00:00
}
/* call another function to do the work
*/
add_vert_defnr ( ob , def_nr , vertnum , weight , assignmode ) ;
}
2002-10-12 11:37:38 +00:00
/* Only available in editmode */
2006-09-03 12:16:14 +00:00
void assign_verts_defgroup ( void )
2002-10-12 11:37:38 +00:00
{
2006-09-03 12:16:14 +00:00
extern float editbutvweight ; /* buttons.c */
2002-10-12 11:37:38 +00:00
Object * ob ;
EditVert * eve ;
2006-09-03 12:16:14 +00:00
bDeformGroup * dg , * eg ;
2002-10-12 11:37:38 +00:00
MDeformWeight * newdw ;
2006-11-11 23:23:15 +00:00
MDeformVert * dvert ;
2006-09-03 12:16:14 +00:00
int i , done ;
2006-12-31 10:51:21 +00:00
if ( multires_level1_test ( ) ) return ;
2002-10-12 11:37:38 +00:00
2006-09-03 12:16:14 +00:00
ob = G . obedit ;
2002-10-12 11:37:38 +00:00
if ( ! ob )
return ;
dg = BLI_findlink ( & ob - > defbase , ob - > actdef - 1 ) ;
if ( ! dg ) {
2004-06-05 05:55:15 +00:00
error ( " No vertex group is active " ) ;
2002-10-12 11:37:38 +00:00
return ;
}
switch ( ob - > type ) {
case OB_MESH :
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
if ( ! CustomData_has_layer ( & G . editMesh - > vdata , CD_MDEFORMVERT ) )
EM_add_data_layer ( & G . editMesh - > vdata , CD_MDEFORMVERT ) ;
2006-11-11 23:23:15 +00:00
2002-10-12 11:37:38 +00:00
/* Go through the list of editverts and assign them */
2006-09-03 12:16:14 +00:00
for ( eve = G . editMesh - > verts . first ; eve ; eve = eve - > next ) {
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
dvert = CustomData_em_get ( & G . editMesh - > vdata , eve - > data , CD_MDEFORMVERT ) ;
2006-11-11 23:23:15 +00:00
if ( dvert & & ( eve - > f & 1 ) ) {
2002-10-12 11:37:38 +00:00
done = 0 ;
/* See if this vert already has a reference to this group */
/* If so: Change its weight */
done = 0 ;
2006-11-11 23:23:15 +00:00
for ( i = 0 ; i < dvert - > totweight ; i + + ) {
eg = BLI_findlink ( & ob - > defbase , dvert - > dw [ i ] . def_nr ) ;
2002-10-12 11:37:38 +00:00
/* Find the actual group */
if ( eg = = dg ) {
2006-11-11 23:23:15 +00:00
dvert - > dw [ i ] . weight = editbutvweight ;
2002-10-12 11:37:38 +00:00
done = 1 ;
break ;
}
}
/* If not: Add the group and set its weight */
if ( ! done ) {
2006-11-11 23:23:15 +00:00
newdw = MEM_callocN ( sizeof ( MDeformWeight ) * ( dvert - > totweight + 1 ) , " deformWeight " ) ;
if ( dvert - > dw ) {
memcpy ( newdw , dvert - > dw , sizeof ( MDeformWeight ) * dvert - > totweight ) ;
MEM_freeN ( dvert - > dw ) ;
2002-10-12 11:37:38 +00:00
}
2006-11-11 23:23:15 +00:00
dvert - > dw = newdw ;
2002-10-12 11:37:38 +00:00
2006-11-11 23:23:15 +00:00
dvert - > dw [ dvert - > totweight ] . weight = editbutvweight ;
dvert - > dw [ dvert - > totweight ] . def_nr = ob - > actdef - 1 ;
2002-10-12 11:37:38 +00:00
2006-11-11 23:23:15 +00:00
dvert - > totweight + + ;
2002-10-12 11:37:38 +00:00
}
}
}
break ;
2006-09-03 12:16:14 +00:00
case OB_LATTICE :
{
BPoint * bp ;
int a , tot ;
if ( editLatt - > dvert = = NULL )
create_dverts ( & editLatt - > id ) ;
tot = editLatt - > pntsu * editLatt - > pntsv * editLatt - > pntsw ;
for ( a = 0 , bp = editLatt - > def ; a < tot ; a + + , bp + + ) {
if ( bp - > f1 & SELECT )
add_vert_defnr ( ob , ob - > actdef - 1 , a , editbutvweight , WEIGHT_REPLACE ) ;
}
}
break ;
2002-10-12 11:37:38 +00:00
default :
2003-05-11 14:29:16 +00:00
printf ( " Assigning deformation groups to unknown object type \n " ) ;
2002-10-12 11:37:38 +00:00
break ;
}
}
2006-09-03 12:16:14 +00:00
/* mesh object mode, lattice can be in editmode */
2003-04-24 00:48:43 +00:00
void remove_vert_defgroup ( Object * ob , bDeformGroup * dg , int vertnum )
{
/* This routine removes the vertex from the specified
* deform group .
*/
int def_nr ;
/* if the object is NULL abort
*/
if ( ! ob )
return ;
/* get the deform number that cooresponds
* to this deform group , and abort if it
* can not be found .
*/
def_nr = get_defgroup_num ( ob , dg ) ;
if ( def_nr < 0 ) return ;
/* call another routine to do the work
*/
remove_vert_def_nr ( ob , def_nr , vertnum ) ;
}
2007-11-27 21:16:47 +00:00
/* for mesh in object mode lattice can be in editmode */
static float get_vert_def_nr ( Object * ob , int def_nr , int vertnum )
{
MDeformVert * dvert = NULL ;
int i ;
/* get the deform vertices corresponding to the
* vertnum
*/
if ( ob - > type = = OB_MESH ) {
if ( ( ( Mesh * ) ob - > data ) - > dvert )
dvert = ( ( Mesh * ) ob - > data ) - > dvert + vertnum ;
}
else if ( ob - > type = = OB_LATTICE ) {
Lattice * lt = ob - > data ;
if ( ob = = G . obedit )
lt = editLatt ;
if ( lt - > dvert )
dvert = lt - > dvert + vertnum ;
}
if ( dvert = = NULL )
return 0.0f ;
for ( i = dvert - > totweight - 1 ; i > = 0 ; i - - )
if ( dvert - > dw [ i ] . def_nr = = def_nr )
return dvert - > dw [ i ] . weight ;
return 0.0f ;
}
/* mesh object mode, lattice can be in editmode */
float get_vert_defgroup ( Object * ob , bDeformGroup * dg , int vertnum )
{
int def_nr ;
if ( ! ob )
return 0.0f ;
def_nr = get_defgroup_num ( ob , dg ) ;
if ( def_nr < 0 ) return 0.0f ;
return get_vert_def_nr ( ob , def_nr , vertnum ) ;
}
2002-10-12 11:37:38 +00:00
/* Only available in editmode */
2006-09-03 12:16:14 +00:00
/* removes from active defgroup, if allverts==0 only selected vertices */
void remove_verts_defgroup ( int allverts )
2002-10-12 11:37:38 +00:00
{
Object * ob ;
EditVert * eve ;
2006-11-11 23:23:15 +00:00
MDeformVert * dvert ;
2002-10-12 11:37:38 +00:00
MDeformWeight * newdw ;
2006-09-03 12:16:14 +00:00
bDeformGroup * dg , * eg ;
2002-10-12 11:37:38 +00:00
int i ;
2006-12-31 10:51:21 +00:00
if ( multires_level1_test ( ) ) return ;
2002-10-12 11:37:38 +00:00
2006-09-03 12:16:14 +00:00
ob = G . obedit ;
2002-10-12 11:37:38 +00:00
if ( ! ob )
return ;
dg = BLI_findlink ( & ob - > defbase , ob - > actdef - 1 ) ;
if ( ! dg ) {
2004-06-05 05:55:15 +00:00
error ( " No vertex group is active " ) ;
2002-10-12 11:37:38 +00:00
return ;
}
switch ( ob - > type ) {
case OB_MESH :
2006-09-03 12:16:14 +00:00
for ( eve = G . editMesh - > verts . first ; eve ; eve = eve - > next ) {
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
dvert = CustomData_em_get ( & G . editMesh - > vdata , eve - > data , CD_MDEFORMVERT ) ;
2008-01-27 10:34:35 +00:00
2006-11-11 23:23:15 +00:00
if ( dvert & & dvert - > dw & & ( ( eve - > f & 1 ) | | allverts ) ) {
for ( i = 0 ; i < dvert - > totweight ; i + + ) {
2002-10-12 11:37:38 +00:00
/* Find group */
2006-11-11 23:23:15 +00:00
eg = BLI_findlink ( & ob - > defbase , dvert - > dw [ i ] . def_nr ) ;
2002-10-12 11:37:38 +00:00
if ( eg = = dg ) {
2006-11-11 23:23:15 +00:00
dvert - > totweight - - ;
if ( dvert - > totweight ) {
newdw = MEM_mallocN ( sizeof ( MDeformWeight ) * ( dvert - > totweight ) , " deformWeight " ) ;
2002-10-12 11:37:38 +00:00
2006-11-11 23:23:15 +00:00
if ( dvert - > dw ) {
memcpy ( newdw , dvert - > dw , sizeof ( MDeformWeight ) * i ) ;
memcpy ( newdw + i , dvert - > dw + i + 1 , sizeof ( MDeformWeight ) * ( dvert - > totweight - i ) ) ;
MEM_freeN ( dvert - > dw ) ;
2002-10-12 11:37:38 +00:00
}
2006-11-11 23:23:15 +00:00
dvert - > dw = newdw ;
2002-10-12 11:37:38 +00:00
}
else {
2006-11-11 23:23:15 +00:00
MEM_freeN ( dvert - > dw ) ;
dvert - > dw = NULL ;
2006-12-01 19:52:04 +00:00
break ;
2002-10-12 11:37:38 +00:00
}
}
}
}
}
break ;
2006-09-03 12:16:14 +00:00
case OB_LATTICE :
if ( editLatt - > dvert ) {
BPoint * bp ;
int a , tot = editLatt - > pntsu * editLatt - > pntsv * editLatt - > pntsw ;
for ( a = 0 , bp = editLatt - > def ; a < tot ; a + + , bp + + ) {
if ( allverts | | ( bp - > f1 & SELECT ) )
remove_vert_defgroup ( ob , dg , a ) ;
2002-10-12 11:37:38 +00:00
}
}
break ;
2006-09-03 12:16:14 +00:00
2002-10-12 11:37:38 +00:00
default :
2006-09-03 12:16:14 +00:00
printf ( " Removing deformation groups from unknown object type \n " ) ;
2002-10-12 11:37:38 +00:00
break ;
}
}
2008-01-27 10:34:35 +00:00
/* Only available in editmode */
/* removes from all defgroup, if allverts==0 only selected vertices */
void remove_verts_defgroups ( int allverts )
{
Object * ob ;
int actdef , defCount ;
if ( multires_level1_test ( ) ) return ;
ob = G . obedit ;
if ( ob = = NULL ) return ;
actdef = ob - > actdef ;
defCount = BLI_countlist ( & ob - > defbase ) ;
if ( defCount = = 0 ) {
error ( " Object has no vertex groups " ) ;
return ;
}
/* To prevent code redundancy, we just use remove_verts_defgroup, but that
* only operates on the active vgroup . So we iterate through all groups , by changing
* active group index
*/
for ( ob - > actdef = 1 ; ob - > actdef < = defCount ; ob - > actdef + + )
remove_verts_defgroup ( allverts ) ;
ob - > actdef = actdef ;
}
2005-08-15 16:12:50 +00:00
void vertexgroup_select_by_name ( Object * ob , char * name )
{
bDeformGroup * curdef ;
int actdef = 1 ;
2006-09-03 12:16:14 +00:00
if ( ob = = NULL ) return ;
2005-08-15 16:12:50 +00:00
for ( curdef = ob - > defbase . first ; curdef ; curdef = curdef - > next , actdef + + ) {
if ( ! strcmp ( curdef - > name , name ) ) {
ob - > actdef = actdef ;
2005-08-21 20:09:50 +00:00
return ;
2005-08-15 16:12:50 +00:00
}
}
2005-08-21 20:09:50 +00:00
ob - > actdef = 0 ; // this signals on painting to create a new one, if a bone in posemode is selected */
2005-08-15 16:12:50 +00:00
}
2007-05-30 10:36:17 +00:00
/* This function provides a shortcut for adding/removing verts from
* vertex groups . It is called by the Ctrl - G hotkey in EditMode for Meshes
* and Lattices . ( currently only restricted to those two )
* It is only responsible for
*/
void vgroup_assign_with_menu ( void )
{
Object * ob = G . obedit ;
int defCount ;
int mode ;
/* prevent crashes */
if ( ob = = NULL ) return ;
defCount = BLI_countlist ( & ob - > defbase ) ;
/* give user choices of adding to current/new or removing from current */
if ( defCount & & ob - > actdef )
2008-01-27 10:34:35 +00:00
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 " ) ;
2007-05-30 10:36:17 +00:00
else
mode = pupmenu ( " Vertex Groups %t|Add Selected to New Group %x1 " ) ;
/* handle choices */
switch ( mode ) {
case 1 : /* add to new group */
add_defgroup ( ob ) ;
assign_verts_defgroup ( ) ;
allqueue ( REDRAWVIEW3D , 1 ) ;
BIF_undo_push ( " Assign to vertex group " ) ;
break ;
case 2 : /* add to current group */
assign_verts_defgroup ( ) ;
allqueue ( REDRAWVIEW3D , 1 ) ;
BIF_undo_push ( " Assign to vertex group " ) ;
break ;
case 3 : /* remove from current group */
remove_verts_defgroup ( 0 ) ;
allqueue ( REDRAWVIEW3D , 1 ) ;
BIF_undo_push ( " Remove from vertex group " ) ;
break ;
2008-01-27 10:34:35 +00:00
case 4 : /* remove from all groups */
remove_verts_defgroups ( 0 ) ;
allqueue ( REDRAWVIEW3D , 1 ) ;
BIF_undo_push ( " Remove from all vertex groups " ) ;
break ;
2007-05-30 10:36:17 +00:00
}
}
/* This function provides a shortcut for commonly used vertex group
* functions - change weight ( not implemented ) , change active group , delete active group ,
* when Ctrl - Shift - G is used in EditMode , for Meshes and Lattices ( only for now ) .
*/
void vgroup_operation_with_menu ( void )
{
Object * ob = G . obedit ;
int defCount ;
int mode ;
/* prevent crashes and useless cases */
if ( ob = = NULL ) return ;
defCount = BLI_countlist ( & ob - > defbase ) ;
if ( defCount = = 0 ) return ;
/* give user choices of adding to current/new or removing from current */
if ( ob - > actdef )
2008-10-26 09:41:59 +00:00
mode = pupmenu ( " Vertex Groups %t|Change Active Group%x1|Delete Active Group%x2|Delete All Groups%x3 " ) ;
2007-05-30 10:36:17 +00:00
else
2008-10-26 09:41:59 +00:00
mode = pupmenu ( " Vertex Groups %t|Change Active Group%x1|Delete All Groups%x3 " ) ;
2007-05-30 10:36:17 +00:00
/* handle choices */
switch ( mode ) {
case 1 : /* change active group*/
{
char * menustr = get_vertexgroup_menustr ( ob ) ;
short nr ;
if ( menustr ) {
nr = pupmenu ( menustr ) ;
if ( ( nr > = 1 ) & & ( nr < = defCount ) )
ob - > actdef = nr ;
MEM_freeN ( menustr ) ;
}
allqueue ( REDRAWBUTSALL , 0 ) ;
}
break ;
case 2 : /* delete active group */
{
del_defgroup ( ob ) ;
2008-10-26 09:41:59 +00:00
allqueue ( REDRAWVIEW3D , 1 ) ;
2007-05-30 10:36:17 +00:00
allqueue ( REDRAWOOPS , 0 ) ;
BIF_undo_push ( " Delete vertex group " ) ;
}
break ;
2008-10-26 09:41:59 +00:00
case 3 : /* delete all groups */
{
del_all_defgroups ( ob ) ;
allqueue ( REDRAWVIEW3D , 1 ) ;
allqueue ( REDRAWOOPS , 0 ) ;
allqueue ( REDRAWBUTSEDIT , 1 ) ;
BIF_undo_push ( " Delete all vertex groups " ) ;
}
break ;
2007-05-30 10:36:17 +00:00
}
}
2005-08-15 16:12:50 +00:00
2004-09-28 16:18:22 +00:00
/* ******************* other deform edit stuff ********** */
void object_apply_deform ( Object * ob )
{
2005-12-19 11:55:31 +00:00
notice ( " Apply Deformation now only availble in Modifier buttons " ) ;
2004-09-28 16:18:22 +00:00
}