Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/lattice.c')
-rw-r--r--source/blender/blenkernel/intern/lattice.c633
1 files changed, 633 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
new file mode 100644
index 00000000000..a6895d2a8ea
--- /dev/null
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -0,0 +1,633 @@
+/**
+ * lattice.c MIXED MODEL
+ * june 2001 ton
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * 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
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "DNA_armature_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_key_types.h"
+#include "DNA_ika_types.h"
+
+#include "BKE_utildefines.h"
+#include "BKE_armature.h"
+#include "BKE_library.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_screen.h"
+#include "BKE_displist.h"
+#include "BKE_lattice.h"
+#include "BKE_key.h"
+#include "BKE_object.h"
+#include "BKE_ika.h"
+
+Lattice *editLatt=0, *deformLatt=0;
+
+float *latticedata=0, latmat[4][4];
+int lt_applyflag= 0;
+
+void resizelattice(Lattice *lt)
+{
+ BPoint *bp;
+ int u, v, w;
+ float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
+
+
+ MEM_freeN(lt->def);
+ lt->def= MEM_callocN(lt->pntsu*lt->pntsv*lt->pntsw*sizeof(BPoint), "lattice bp");
+
+ bp= lt->def;
+
+ while(lt->pntsu*lt->pntsv*lt->pntsw > 32000) {
+ if( lt->pntsu>=lt->pntsv && lt->pntsu>=lt->pntsw) lt->pntsu--;
+ else if( lt->pntsv>=lt->pntsu && lt->pntsv>=lt->pntsw) lt->pntsv--;
+ else lt->pntsw--;
+ }
+
+ calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
+ calc_lat_fudu(lt->flag, lt->pntsv, &fv, &dv);
+ calc_lat_fudu(lt->flag, lt->pntsw, &fw, &dw);
+
+ vec[2]= fw;
+ for(w=0; w<lt->pntsw; w++) {
+ vec[1]= fv;
+ for(v=0; v<lt->pntsv; v++) {
+ vec[0]= fu;
+ for(u=0; u<lt->pntsu; u++, bp++) {
+ VECCOPY(bp->vec, vec);
+ vec[0]+= du;
+ }
+ vec[1]+= dv;
+ }
+ vec[2]+= dw;
+ }
+}
+
+Lattice *add_lattice()
+{
+ Lattice *lt;
+
+ lt= alloc_libblock(&G.main->latt, ID_LT, "Lattice");
+
+ lt->pntsu=lt->pntsv=lt->pntsw= 2;
+ lt->flag= LT_GRID;
+
+ lt->typeu= lt->typev= lt->typew= KEY_BSPLINE;
+
+ /* tijdelijk */
+ lt->def= MEM_callocN(sizeof(BPoint), "lattvert");
+
+ resizelattice(lt); /* maakt een regelmatige lattice */
+
+ return lt;
+}
+
+Lattice *copy_lattice(Lattice *lt)
+{
+ Lattice *ltn;
+
+ ltn= copy_libblock(lt);
+ ltn->def= MEM_dupallocN(lt->def);
+
+ id_us_plus((ID *)ltn->ipo);
+
+ ltn->key= copy_key(ltn->key);
+ if(ltn->key) ltn->key->from= (ID *)ltn;
+
+ return ltn;
+}
+
+void free_lattice(Lattice *lt)
+{
+ if(lt->def) MEM_freeN(lt->def);
+}
+
+
+void make_local_lattice(Lattice *lt)
+{
+ Object *ob;
+ Lattice *ltn;
+ int local=0, lib=0;
+
+ /* - zijn er alleen lib users: niet doen
+ * - zijn er alleen locale users: flag zetten
+ * - mixed: copy
+ */
+
+ if(lt->id.lib==0) return;
+ if(lt->id.us==1) {
+ lt->id.lib= 0;
+ lt->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)lt, 0);
+ return;
+ }
+
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->data==lt) {
+ if(ob->id.lib) lib= 1;
+ else local= 1;
+ }
+ ob= ob->id.next;
+ }
+
+ if(local && lib==0) {
+ lt->id.lib= 0;
+ lt->id.flag= LIB_LOCAL;
+ new_id(0, (ID *)lt, 0);
+ }
+ else if(local && lib) {
+ ltn= copy_lattice(lt);
+ ltn->id.us= 0;
+
+ ob= G.main->object.first;
+ while(ob) {
+ if(ob->data==lt) {
+
+ if(ob->id.lib==0) {
+ ob->data= ltn;
+ ltn->id.us++;
+ lt->id.us--;
+ }
+ }
+ ob= ob->id.next;
+ }
+ }
+}
+
+
+
+void calc_lat_fudu(int flag, int res, float *fu, float *du)
+{
+
+ if(res==1) {
+ *fu= 0.0;
+ *du= 0.0;
+ }
+ else if(flag & LT_GRID) {
+ *fu= -0.5f*(res-1);
+ *du= 1.0f;
+ }
+ else {
+ *fu= -1.0f;
+ *du= 2.0f/(res-1);
+ }
+
+}
+
+void init_latt_deform(Object *oblatt, Object *ob)
+{
+ /* we maken een array met alle verschillen */
+ BPoint *bp;
+ float *fp, imat[4][4];
+ float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
+ int u, v, w;
+
+ if(oblatt==G.obedit) deformLatt= editLatt;
+ else deformLatt= oblatt->data;
+
+ fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
+
+ bp= deformLatt->def;
+
+ if(ob) where_is_object(ob);
+
+ /* bijv bij particle systeem: ob==0 */
+ if(ob==0) {
+ /* in deformspace, matrix berekenen */
+ Mat4Invert(latmat, oblatt->obmat);
+
+ /* terug: in deform array verwerken */
+ Mat4Invert(imat, latmat);
+ }
+ else {
+ /* in deformspace, matrix berekenen */
+ Mat4Invert(imat, oblatt->obmat);
+ Mat4MulMat4(latmat, ob->obmat, imat);
+
+ /* terug: in deform array verwerken */
+ Mat4Invert(imat, latmat);
+ }
+ calc_lat_fudu(deformLatt->flag, deformLatt->pntsu, &fu, &du);
+ calc_lat_fudu(deformLatt->flag, deformLatt->pntsv, &fv, &dv);
+ calc_lat_fudu(deformLatt->flag, deformLatt->pntsw, &fw, &dw);
+
+ /* we berekenen hier steeds de u v w lattice coordinaten, weinig reden ze te onthouden */
+
+ vec[2]= fw;
+ for(w=0; w<deformLatt->pntsw; w++) {
+ vec[1]= fv;
+ for(v=0; v<deformLatt->pntsv; v++) {
+ vec[0]= fu;
+ for(u=0; u<deformLatt->pntsu; u++, bp++) {
+
+ VecSubf(fp, bp->vec, vec);
+ Mat4Mul3Vecfl(imat, fp);
+
+ vec[0]+= du;
+ fp+= 3;
+ }
+ vec[1]+= dv;
+ }
+ vec[2]+= dw;
+ }
+}
+
+void calc_latt_deform(float *co)
+{
+ Lattice *lt;
+ float fu, du, u, v, w, tu[4], tv[4], tw[4];
+ float *fpw, *fpv, *fpu, vec[3];
+ int ui, vi, wi, uu, vv, ww;
+
+ if(latticedata==0) return;
+
+ lt= deformLatt; /* kortere notatie! */
+
+ /* co is in lokale coords, met latmat behandelen */
+
+ VECCOPY(vec, co);
+ Mat4MulVecfl(latmat, vec);
+
+ /* u v w coords */
+
+ if(lt->pntsu>1) {
+ calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
+ u= (vec[0]-fu)/du;
+ ui= (int)floor(u);
+ u -= ui;
+ set_four_ipo(u, tu, lt->typeu);
+ }
+ else {
+ tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
+ ui= 0;
+ }
+
+ if(lt->pntsv>1) {
+ calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du);
+ v= (vec[1]-fu)/du;
+ vi= (int)floor(v);
+ v -= vi;
+ set_four_ipo(v, tv, lt->typev);
+ }
+ else {
+ tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
+ vi= 0;
+ }
+
+ if(lt->pntsw>1) {
+ calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du);
+ w= (vec[2]-fu)/du;
+ wi= (int)floor(w);
+ w -= wi;
+ set_four_ipo(w, tw, lt->typew);
+ }
+ else {
+ tw[0]= tw[2]= tw[3]= 0.0; tw[1]= 1.0;
+ wi= 0;
+ }
+
+ for(ww= wi-1; ww<=wi+2; ww++) {
+ w= tw[ww-wi+1];
+
+ if(w!=0.0) {
+ if(ww>0) {
+ if(ww<lt->pntsw) fpw= latticedata + 3*ww*lt->pntsu*lt->pntsv;
+ else fpw= latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
+ }
+ else fpw= latticedata;
+
+ for(vv= vi-1; vv<=vi+2; vv++) {
+ v= w*tv[vv-vi+1];
+
+ if(v!=0.0) {
+ if(vv>0) {
+ if(vv<lt->pntsv) fpv= fpw + 3*vv*lt->pntsu;
+ else fpv= fpw + 3*(lt->pntsv-1)*lt->pntsu;
+ }
+ else fpv= fpw;
+
+ for(uu= ui-1; uu<=ui+2; uu++) {
+ u= v*tu[uu-ui+1];
+
+ if(u!=0.0) {
+ if(uu>0) {
+ if(uu<lt->pntsu) fpu= fpv + 3*uu;
+ else fpu= fpv + 3*(lt->pntsu-1);
+ }
+ else fpu= fpv;
+
+ co[0]+= u*fpu[0];
+ co[1]+= u*fpu[1];
+ co[2]+= u*fpu[2];
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void end_latt_deform()
+{
+
+ MEM_freeN(latticedata);
+ latticedata= 0;
+}
+
+
+int object_deform(Object *ob)
+{
+ Mesh *me;
+ Curve *cu;
+ DispList *dl;
+ MVert *mvert;
+ float *fp;
+ int a, tot;
+
+ if(ob->parent==0) return 0;
+
+ /* altijd proberen in deze fie de hele deform te doen: apply! */
+
+ if(ob->parent->type==OB_LATTICE) {
+
+ init_latt_deform(ob->parent, ob);
+
+ if(ob->type==OB_MESH) {
+ me= ob->data;
+
+ dl= find_displist_create(&ob->disp, DL_VERTS);
+
+ mvert= me->mvert;
+ if(dl->verts) MEM_freeN(dl->verts);
+ dl->nr= me->totvert;
+ dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
+
+ for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
+ if(lt_applyflag) calc_latt_deform(mvert->co);
+ else {
+ VECCOPY(fp, mvert->co);
+ calc_latt_deform(fp);
+ }
+ }
+ }
+ else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+
+ cu= ob->data;
+ if(lt_applyflag) {
+ Nurb *nu;
+ BPoint *bp;
+
+ nu= cu->nurb.first;
+ while(nu) {
+ if(nu->bp) {
+ a= nu->pntsu*nu->pntsv;
+ bp= nu->bp;
+ while(a--) {
+ calc_latt_deform(bp->vec);
+ bp++;
+ }
+ }
+ nu= nu->next;
+ }
+ }
+
+ /* when apply, do this too, looks more interactive */
+ dl= cu->disp.first;
+ while(dl) {
+
+ fp= dl->verts;
+
+ if(dl->type==DL_INDEX3) tot=dl->parts;
+ else tot= dl->nr*dl->parts;
+
+ for(a=0; a<tot; a++, fp+=3) {
+ calc_latt_deform(fp);
+ }
+
+ dl= dl->next;
+ }
+ }
+ end_latt_deform();
+
+ boundbox_displist(ob);
+
+ return 1;
+ }
+ else if(ob->parent->type==OB_ARMATURE) {
+ if (ob->partype != PARSKEL){
+ return 0;
+ }
+
+ init_armature_deform (ob->parent, ob);
+
+ switch (ob->type){
+ case OB_MESH:
+ me= ob->data;
+
+ dl= find_displist_create(&ob->disp, DL_VERTS);
+
+ mvert= me->mvert;
+ if(dl->verts) MEM_freeN(dl->verts);
+ dl->nr= me->totvert;
+ dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
+
+ for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
+ if(lt_applyflag){
+ calc_armature_deform(ob->parent, mvert->co, a);
+ }
+ else {
+ VECCOPY(fp, mvert->co);
+ calc_armature_deform(ob->parent, fp, a);
+ }
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ boundbox_displist(ob);
+ return 1;
+ }
+ else if(ob->parent->type==OB_IKA) {
+
+ Ika *ika;
+
+ if(ob->partype!=PARSKEL) return 0;
+
+ ika= ob->parent->data;
+ if(ika->def==0) return 0;
+
+ init_skel_deform(ob->parent, ob);
+
+ if(ob->type==OB_MESH) {
+ me= ob->data;
+
+ dl= find_displist_create(&ob->disp, DL_VERTS);
+
+ mvert= me->mvert;
+ if(dl->verts) MEM_freeN(dl->verts);
+ dl->nr= me->totvert;
+ dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
+
+ for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
+ if(lt_applyflag) calc_skel_deform(ika, mvert->co);
+ else {
+ VECCOPY(fp, mvert->co);
+ calc_skel_deform(ika, fp);
+ }
+ }
+ }
+ else if ELEM(ob->type, OB_CURVE, OB_SURF) {
+
+ cu= ob->data;
+ if(lt_applyflag) {
+ Nurb *nu;
+ BPoint *bp;
+
+ nu= cu->nurb.first;
+ while(nu) {
+ if(nu->bp) {
+ a= nu->pntsu*nu->pntsv;
+ bp= nu->bp;
+ while(a--) {
+ calc_skel_deform(ika, bp->vec);
+ bp++;
+ }
+ }
+ nu= nu->next;
+ }
+ }
+
+ /* when apply, do this too, looks more interactive */
+ dl= cu->disp.first;
+ while(dl) {
+
+ fp= dl->verts;
+ tot= dl->nr*dl->parts;
+ for(a=0; a<tot; a++, fp+=3) {
+ calc_skel_deform(ika, fp);
+ }
+
+ dl= dl->next;
+ }
+ }
+
+ boundbox_displist(ob);
+
+ return 1;
+ }
+
+ return 0;
+
+}
+
+BPoint *latt_bp(Lattice *lt, int u, int v, int w)
+{
+ return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
+}
+
+void outside_lattice(Lattice *lt)
+{
+ BPoint *bp, *bp1, *bp2;
+ int u, v, w;
+ float fac1, du=0.0, dv=0.0, dw=0.0;
+
+ bp= lt->def;
+
+ if(lt->pntsu>1) du= 1.0f/((float)lt->pntsu-1);
+ if(lt->pntsv>1) dv= 1.0f/((float)lt->pntsv-1);
+ if(lt->pntsw>1) dw= 1.0f/((float)lt->pntsw-1);
+
+ for(w=0; w<lt->pntsw; w++) {
+
+ for(v=0; v<lt->pntsv; v++) {
+
+ for(u=0; u<lt->pntsu; u++, bp++) {
+ if(u==0 || v==0 || w==0 || u==lt->pntsu-1 || v==lt->pntsv-1 || w==lt->pntsw-1);
+ else {
+
+ bp->hide= 1;
+ bp->f1 &= ~SELECT;
+
+ /* u extrema */
+ bp1= latt_bp(lt, 0, v, w);
+ bp2= latt_bp(lt, lt->pntsu-1, v, w);
+
+ fac1= du*u;
+ bp->vec[0]= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
+ bp->vec[1]= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
+ bp->vec[2]= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
+
+ /* v extrema */
+ bp1= latt_bp(lt, u, 0, w);
+ bp2= latt_bp(lt, u, lt->pntsv-1, w);
+
+ fac1= dv*v;
+ bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
+ bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
+ bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
+
+ /* w extrema */
+ bp1= latt_bp(lt, u, v, 0);
+ bp2= latt_bp(lt, u, v, lt->pntsw-1);
+
+ fac1= dw*w;
+ bp->vec[0]+= (1.0f-fac1)*bp1->vec[0] + fac1*bp2->vec[0];
+ bp->vec[1]+= (1.0f-fac1)*bp1->vec[1] + fac1*bp2->vec[1];
+ bp->vec[2]+= (1.0f-fac1)*bp1->vec[2] + fac1*bp2->vec[2];
+
+ VecMulf(bp->vec, 0.3333333f);
+
+ }
+ }
+
+ }
+
+ }
+
+}