Copy Shape Verts
In mesh editmode, while editing a shape, select some verts, W Key, "Copy Shape Verts". You will be presented with a list of shapes and once chosen, the selected verts will be moved to the position of the verts from the chosen shape. Most handy use would be reverting part of a shape back to basis e.g. Making eyebrow shapes, add a key and model the eyebrow shape symetrically with the x-mirror tool Go out of editmode, copy that shape Go into each shape and revert 1 side to basis If the mesh has had verts added/removed since last entering editmode, you need to TAB-TAB first before copying
This commit is contained in:
@@ -197,5 +197,7 @@ int editedge_containsVert(struct EditEdge *eed, struct EditVert *eve);
|
|||||||
int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
|
int editface_containsVert(struct EditFace *efa, struct EditVert *eve);
|
||||||
int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
|
int editface_containsEdge(struct EditFace *efa, struct EditEdge *eed);
|
||||||
|
|
||||||
|
void shape_copy_select_from(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -54,6 +54,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
|
|||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_screen_types.h"
|
#include "DNA_screen_types.h"
|
||||||
#include "DNA_view3d_types.h"
|
#include "DNA_view3d_types.h"
|
||||||
|
#include "DNA_key_types.h"
|
||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_arithb.h"
|
#include "BLI_arithb.h"
|
||||||
@@ -5348,3 +5349,83 @@ void mesh_rip(void)
|
|||||||
Transform();
|
Transform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void shape_copy_from(KeyBlock* fromKey)
|
||||||
|
{
|
||||||
|
EditMesh *em = G.editMesh;
|
||||||
|
EditVert *ev = NULL;
|
||||||
|
|
||||||
|
for(ev = em->verts.first; ev ; ev = ev->next){
|
||||||
|
if(ev->f & SELECT){
|
||||||
|
float *data;
|
||||||
|
//Check that index is valid in fromKey
|
||||||
|
|
||||||
|
//Copy co from fromKey->data
|
||||||
|
data = fromKey->data;
|
||||||
|
|
||||||
|
VECCOPY(ev->co, data+(ev->keyindex*3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BIF_undo_push("Copy Blendshape Verts");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void shape_copy_select_from()
|
||||||
|
{
|
||||||
|
Mesh* me = (Mesh*)G.obedit->data;
|
||||||
|
EditMesh *em = G.editMesh;
|
||||||
|
EditVert *ev = NULL;
|
||||||
|
int totverts = 0;
|
||||||
|
|
||||||
|
Key* ky = NULL;
|
||||||
|
KeyBlock* kb = NULL;
|
||||||
|
int maxlen=32, nr=0, a=0;
|
||||||
|
char *menu;
|
||||||
|
|
||||||
|
if(me->key){
|
||||||
|
ky = me->key;
|
||||||
|
} else {
|
||||||
|
error("Object Has No Key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ky->block.first){
|
||||||
|
for(kb=ky->block.first;kb;kb = kb->next){
|
||||||
|
maxlen += 40; // Size of a block name
|
||||||
|
}
|
||||||
|
menu = MEM_callocN(maxlen, "Copy Shape Menu Text");
|
||||||
|
strcpy(menu, "Copy Vert Positions from Shape %t|");
|
||||||
|
for(kb=ky->block.first;kb;kb = kb->next){
|
||||||
|
sprintf(menu,"%s %s %cx%d|",menu,kb->name,'%',a);
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
nr = pupmenu(menu);
|
||||||
|
MEM_freeN(menu);
|
||||||
|
} else {
|
||||||
|
error("Object Has No Blendshapes");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a = 0;
|
||||||
|
|
||||||
|
for(kb=ky->block.first;kb;kb = kb->next){
|
||||||
|
if(a == nr){
|
||||||
|
|
||||||
|
for(ev = em->verts.first;ev;ev = ev->next){
|
||||||
|
totverts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(me->totvert != totverts){
|
||||||
|
error("Shape Has had Verts Added/Removed, please cycle editmode before copying");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shape_copy_from(kb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
a++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -2069,7 +2069,7 @@ void special_editmenu(void)
|
|||||||
}
|
}
|
||||||
else if(G.obedit->type==OB_MESH) {
|
else if(G.obedit->type==OB_MESH) {
|
||||||
|
|
||||||
nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15");
|
nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15|Copy Shape Verts%x16");
|
||||||
|
|
||||||
switch(nr) {
|
switch(nr) {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -2137,6 +2137,9 @@ void special_editmenu(void)
|
|||||||
case 15:
|
case 15:
|
||||||
mesh_set_smooth_faces(0);
|
mesh_set_smooth_faces(0);
|
||||||
break;
|
break;
|
||||||
|
case 16:
|
||||||
|
shape_copy_select_from();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
|
||||||
|
Reference in New Issue
Block a user