bugfix [#21036] crash with glsl shading
[blender.git] / source / blender / blenkernel / intern / key.c
index 61f51d61e0b08f025ff745817c9712513de27113..1e1c945d386acfd9811fbbac7a0ec601bbba8ffa 100644 (file)
@@ -32,6 +32,7 @@
 
 #include <math.h>
 #include <string.h>
+#include <stddef.h>
 
 #include "MEM_guardedalloc.h"
 
@@ -51,6 +52,7 @@
 #include "BKE_action.h"
 #include "BKE_blender.h"
 #include "BKE_curve.h"
+#include "BKE_customdata.h"
 #include "BKE_global.h"
 #include "BKE_key.h"
 #include "BKE_lattice.h"
@@ -998,6 +1000,8 @@ static float *get_weights_array(Object *ob, char *vgroup)
 {
        bDeformGroup *curdef;
        MDeformVert *dvert= NULL;
+       EditMesh *em= NULL;
+       EditVert *eve;
        int totvert= 0, index= 0;
        
        /* no vgroup string set? */
@@ -1008,6 +1012,9 @@ static float *get_weights_array(Object *ob, char *vgroup)
                Mesh *me= ob->data;
                dvert= me->dvert;
                totvert= me->totvert;
+
+               if(me->edit_mesh && me->edit_mesh->totvert == totvert)
+                       em= me->edit_mesh;
        }
        else if(ob->type==OB_LATTICE) {
                Lattice *lt= ob->data;
@@ -1027,15 +1034,32 @@ static float *get_weights_array(Object *ob, char *vgroup)
                int i, j;
                
                weights= MEM_callocN(totvert*sizeof(float), "weights");
-               
-               for (i=0; i < totvert; i++, dvert++) {
-                       for(j=0; j<dvert->totweight; j++) {
-                               if (dvert->dw[j].def_nr == index) {
-                                       weights[i]= dvert->dw[j].weight;
-                                       break;
+
+               if(em) {
+                       for(i=0, eve=em->verts.first; eve; eve=eve->next, i++) {
+                               dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
+
+                               if(dvert) {
+                                       for(j=0; j<dvert->totweight; j++) {
+                                               if(dvert->dw[j].def_nr == index) {
+                                                       weights[i]= dvert->dw[j].weight;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               else {
+                       for(i=0; i < totvert; i++, dvert++) {
+                               for(j=0; j<dvert->totweight; j++) {
+                                       if(dvert->dw[j].def_nr == index) {
+                                               weights[i]= dvert->dw[j].weight;
+                                               break;
+                                       }
                                }
                        }
                }
+
                return weights;
        }
        return NULL;
@@ -1192,11 +1216,11 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
 #endif // XXX old animation system
                
                        flag= setkeys(ctime, &key->block, k, t, 0);
-
+                       
                        if(flag==0)
-                               ; /* do_key(a, a+step, tot, (char *)out, key, k, t, 0); */
+                               do_key(a, a+step, tot, (char *)out, key, actkb, k, t, 0);
                        else
-                               ; /* cp_key(a, a+step, tot, (char *)out, key, k[2],0); */
+                               cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, 0);
                }
        }
        else {
@@ -1395,6 +1419,55 @@ Key *ob_get_key(Object *ob)
        return NULL;
 }
 
+KeyBlock *add_keyblock(Key *key, char *name)
+{
+       KeyBlock *kb;
+       float curpos= -0.1;
+       int tot;
+       
+       kb= key->block.last;
+       if(kb) curpos= kb->pos;
+       
+       kb= MEM_callocN(sizeof(KeyBlock), "Keyblock");
+       BLI_addtail(&key->block, kb);
+       kb->type= KEY_CARDINAL;
+       
+       tot= BLI_countlist(&key->block);
+       if(name) {
+               strncpy(kb->name, name, sizeof(kb->name));
+       } else {
+               if(tot==1) strcpy(kb->name, "Basis");
+               else sprintf(kb->name, "Key %d", tot-1);
+       }
+
+       BLI_uniquename(&key->block, kb, "Key", '.', offsetof(KeyBlock, name), sizeof(kb->name));
+
+       // XXX this is old anim system stuff? (i.e. the 'index' of the shapekey)
+       kb->adrcode= tot-1;
+       
+       key->totkey++;
+       if(key->totkey==1) key->refkey= kb;
+       
+       kb->slidermin= 0.0f;
+       kb->slidermax= 1.0f;
+       
+       // XXX kb->pos is the confusing old horizontal-line RVK crap in old IPO Editor...
+       if(key->type == KEY_RELATIVE) 
+               kb->pos= curpos+0.1;
+       else {
+#if 0 // XXX old animation system
+               curpos= bsystem_time(scene, 0, (float)CFRA, 0.0);
+               if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) {
+                       curpos /= 100.0;
+               }
+               kb->pos= curpos;
+               
+               sort_keys(key);
+#endif // XXX old animation system
+       }
+       return kb;
+}
+
 /* only the active keyblock */
 KeyBlock *ob_get_keyblock(Object *ob) 
 {
@@ -1408,6 +1481,16 @@ KeyBlock *ob_get_keyblock(Object *ob)
        return NULL;
 }
 
+KeyBlock *ob_get_reference_keyblock(Object *ob)
+{
+       Key *key= ob_get_key(ob);
+       
+       if (key)
+               return key->refkey;
+
+       return NULL;
+}
+
 /* get the appropriate KeyBlock given an index */
 KeyBlock *key_get_keyblock(Key *key, int index)
 {
@@ -1463,3 +1546,185 @@ char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb)
        /* return the path */
        return RNA_path_from_ID_to_property(&ptr, prop);
 }
+
+
+/* conversion functions */
+
+/************************* Lattice ************************/
+void latt_to_key(Lattice *lt, KeyBlock *kb)
+{
+       BPoint *bp;
+       float *fp;
+       int a, tot;
+
+       tot= lt->pntsu*lt->pntsv*lt->pntsw;
+       if(tot==0) return;
+
+       if(kb->data) MEM_freeN(kb->data);
+
+       kb->data= MEM_callocN(lt->key->elemsize*tot, "kb->data");
+       kb->totelem= tot;
+
+       bp= lt->def;
+       fp= kb->data;
+       for(a=0; a<kb->totelem; a++, fp+=3, bp++) {
+               VECCOPY(fp, bp->vec);
+       }
+}
+
+void key_to_latt(KeyBlock *kb, Lattice *lt)
+{
+       BPoint *bp;
+       float *fp;
+       int a, tot;
+
+       bp= lt->def;
+       fp= kb->data;
+
+       tot= lt->pntsu*lt->pntsv*lt->pntsw;
+       tot= MIN2(kb->totelem, tot);
+
+       for(a=0; a<tot; a++, fp+=3, bp++) {
+               VECCOPY(bp->vec, fp);
+       }
+}
+
+/************************* Curve ************************/
+void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb)
+{
+       Nurb *nu;
+       BezTriple *bezt;
+       BPoint *bp;
+       float *fp;
+       int a, tot;
+
+       /* count */
+       tot= count_curveverts(nurb);
+       if(tot==0) return;
+
+       if(kb->data) MEM_freeN(kb->data);
+
+       kb->data= MEM_callocN(cu->key->elemsize*tot, "kb->data");
+       kb->totelem= tot;
+
+       nu= nurb->first;
+       fp= kb->data;
+       while(nu) {
+
+               if(nu->bezt) {
+                       bezt= nu->bezt;
+                       a= nu->pntsu;
+                       while(a--) {
+                               VECCOPY(fp, bezt->vec[0]);
+                               fp+= 3;
+                               VECCOPY(fp, bezt->vec[1]);
+                               fp+= 3;
+                               VECCOPY(fp, bezt->vec[2]);
+                               fp+= 3;
+                               fp[0]= bezt->alfa;
+                               fp+= 3; /* alphas */
+                               bezt++;
+                       }
+               }
+               else {
+                       bp= nu->bp;
+                       a= nu->pntsu*nu->pntsv;
+                       while(a--) {
+                               VECCOPY(fp, bp->vec);
+                               fp[3]= bp->alfa;
+
+                               fp+= 4;
+                               bp++;
+                       }
+               }
+               nu= nu->next;
+       }
+}
+
+void key_to_curve(KeyBlock *kb, Curve  *cu, ListBase *nurb)
+{
+       Nurb *nu;
+       BezTriple *bezt;
+       BPoint *bp;
+       float *fp;
+       int a, tot;
+
+       nu= nurb->first;
+       fp= kb->data;
+
+       tot= count_curveverts(nurb);
+
+       tot= MIN2(kb->totelem, tot);
+
+       while(nu && tot>0) {
+
+               if(nu->bezt) {
+                       bezt= nu->bezt;
+                       a= nu->pntsu;
+                       while(a-- && tot>0) {
+                               VECCOPY(bezt->vec[0], fp);
+                               fp+= 3;
+                               VECCOPY(bezt->vec[1], fp);
+                               fp+= 3;
+                               VECCOPY(bezt->vec[2], fp);
+                               fp+= 3;
+                               bezt->alfa= fp[0];
+                               fp+= 3; /* alphas */
+
+                               tot-= 3;
+                               bezt++;
+                       }
+               }
+               else {
+                       bp= nu->bp;
+                       a= nu->pntsu*nu->pntsv;
+                       while(a-- && tot>0) {
+                               VECCOPY(bp->vec, fp);
+                               bp->alfa= fp[3];
+
+                               fp+= 4;
+                               tot--;
+                               bp++;
+                       }
+               }
+               nu= nu->next;
+       }
+}
+
+/************************* Mesh ************************/
+void mesh_to_key(Mesh *me, KeyBlock *kb)
+{
+       MVert *mvert;
+       float *fp;
+       int a;
+
+       if(me->totvert==0) return;
+
+       if(kb->data) MEM_freeN(kb->data);
+
+       kb->data= MEM_callocN(me->key->elemsize*me->totvert, "kb->data");
+       kb->totelem= me->totvert;
+
+       mvert= me->mvert;
+       fp= kb->data;
+       for(a=0; a<kb->totelem; a++, fp+=3, mvert++) {
+               VECCOPY(fp, mvert->co);
+
+       }
+}
+
+void key_to_mesh(KeyBlock *kb, Mesh *me)
+{
+       MVert *mvert;
+       float *fp;
+       int a, tot;
+
+       mvert= me->mvert;
+       fp= kb->data;
+
+       tot= MIN2(kb->totelem, me->totvert);
+
+       for(a=0; a<tot; a++, fp+=3, mvert++) {
+               VECCOPY(mvert->co, fp);
+       }
+}