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.c281
1 files changed, 190 insertions, 91 deletions
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 8f463886b3f..df0f9e7d8f8 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -46,6 +46,7 @@
#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_lattice_types.h"
@@ -62,6 +63,7 @@
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
@@ -74,45 +76,120 @@
#include "blendef.h"
-Lattice *editLatt=0, *deformLatt=0;
+Lattice *editLatt=0;
+static Lattice *deformLatt=0;
-float *latticedata=0, latmat[4][4];
+static float *latticedata=0, latmat[4][4];
-void resizelattice(Lattice *lt)
+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 resizelattice(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
{
BPoint *bp;
- int u, v, w;
- float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
+ int i, u, v, w;
+ float fu, fv, fw, uc, vc, wc, du=0.0, dv=0.0, dw=0.0;
+ float *co, (*vertexCos)[3] = NULL;
+
+ while(uNew*vNew*wNew > 32000) {
+ if( uNew>=vNew && uNew>=wNew) uNew--;
+ else if( vNew>=uNew && vNew>=wNew) vNew--;
+ else wNew--;
+ }
+
+ vertexCos = MEM_mallocN(sizeof(*vertexCos)*uNew*vNew*wNew, "tmp_vcos");
+
+ calc_lat_fudu(lt->flag, uNew, &fu, &du);
+ calc_lat_fudu(lt->flag, vNew, &fv, &dv);
+ calc_lat_fudu(lt->flag, wNew, &fw, &dw);
+
+ /* If old size is different then resolution changed in interface,
+ * try to do clever reinit of points. Pretty simply idea, we just
+ * deform new verts by old lattice, but scaling them to match old
+ * size first.
+ */
+ if (ltOb) {
+ if (uNew!=1 && lt->pntsu!=1) {
+ fu = lt->fu;
+ du = (lt->pntsu-1)*lt->du/(uNew-1);
+ }
+
+ if (vNew!=1 && lt->pntsv!=1) {
+ fv = lt->fv;
+ dv = (lt->pntsv-1)*lt->dv/(vNew-1);
+ }
+
+ if (wNew!=1 && lt->pntsw!=1) {
+ fw = lt->fw;
+ dw = (lt->pntsw-1)*lt->dw/(wNew-1);
+ }
+ }
+
+ co = vertexCos[0];
+ for(w=0,wc=fw; w<wNew; w++,wc+=dw) {
+ for(v=0,vc=fv; v<vNew; v++,vc+=dv) {
+ for(u=0,uc=fu; u<uNew; u++,co+=3,uc+=du) {
+ co[0] = uc;
+ co[1] = vc;
+ co[2] = wc;
+ }
+ }
+ }
+ if (ltOb) {
+ float mat[4][4];
+ int typeu = lt->typeu, typev = lt->typev, typew = lt->typew;
+
+ /* works best if we force to linear type (endpoints match) */
+ lt->typeu = lt->typev = lt->typew = KEY_LINEAR;
+
+ /* prevent using deformed locations */
+ freedisplist(&ltOb->disp);
+
+ Mat4CpyMat4(mat, ltOb->obmat);
+ Mat4One(ltOb->obmat);
+ lattice_deform_verts(ltOb, NULL, vertexCos, uNew*vNew*wNew);
+ Mat4CpyMat4(ltOb->obmat, mat);
+
+ lt->typeu = typeu;
+ lt->typev = typev;
+ lt->typew = typew;
+ }
+
+ lt->fu = fu;
+ lt->fv = fv;
+ lt->fw = fw;
+ lt->du = du;
+ lt->dv = dv;
+ lt->dw = dw;
+
+ lt->pntsu = uNew;
+ lt->pntsv = vNew;
+ lt->pntsw = wNew;
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;
+ for (i=0; i<lt->pntsu*lt->pntsv*lt->pntsw; i++,bp++) {
+ VECCOPY(bp->vec, vertexCos[i]);
}
+
+ MEM_freeN(vertexCos);
}
Lattice *add_lattice()
@@ -121,15 +198,12 @@ Lattice *add_lattice()
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;
- /* temporally */
- lt->def= MEM_callocN(sizeof(BPoint), "lattvert");
-
- resizelattice(lt); /* creates a uniform lattice */
+ lt->def= MEM_callocN(sizeof(BPoint), "lattvert"); /* temporary */
+ resizelattice(lt, 2, 2, 2, NULL); /* creates a uniform lattice */
return lt;
}
@@ -207,45 +281,20 @@ void make_local_lattice(Lattice *lt)
}
}
-
-
-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 make an array with all differences */
- BPoint *bp;
+ /* we make an array with all differences */
+ Lattice *lt = deformLatt = (oblatt==G.obedit)?editLatt:oblatt->data;
+ BPoint *bp = lt->def;
+ DispList *dl = find_displist(&oblatt->disp, DL_VERTS);
+ float *co = dl?dl->verts:NULL;
float *fp, imat[4][4];
- float vec[3], fu, fv, fw, du=0.0, dv=0.0, dw=0.0;
+ float fu, fv, fw;
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");
- do_latt_key(oblatt->data);
- bp= deformLatt->def;
-
- //if(ob) where_is_object(ob); causes lag here, but why! (ton)
-
- /* for example with a particle system: ob==0 */
+ /* for example with a particle system: ob==0 */
if(ob==0) {
/* in deformspace, calc matrix */
Mat4Invert(latmat, oblatt->obmat);
@@ -261,35 +310,30 @@ void init_latt_deform(Object *oblatt, Object *ob)
/* back: put in deform array */
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 keep calculating the u v w lattice coordinates, not enough reason to store that */
- 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);
+ for(w=0,fw=lt->fw; w<lt->pntsw; w++,fw+=lt->dw) {
+ for(v=0,fv=lt->fv; v<lt->pntsv; v++, fv+=lt->dv) {
+ for(u=0,fu=lt->fu; u<lt->pntsu; u++, bp++, co+=3, fp+=3, fu+=lt->du) {
+ if (dl) {
+ fp[0] = co[0] - fu;
+ fp[1] = co[1] - fv;
+ fp[2] = co[2] - fw;
+ } else {
+ fp[0] = bp->vec[0] - fu;
+ fp[1] = bp->vec[1] - fv;
+ fp[2] = bp->vec[2] - fw;
+ }
+
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 u, v, w, tu[4], tv[4], tw[4];
float *fpw, *fpv, *fpu, vec[3];
int ui, vi, wi, uu, vv, ww;
@@ -305,8 +349,7 @@ void calc_latt_deform(float *co)
/* u v w coords */
if(lt->pntsu>1) {
- calc_lat_fudu(lt->flag, lt->pntsu, &fu, &du);
- u= (vec[0]-fu)/du;
+ u= (vec[0]-lt->fu)/lt->du;
ui= (int)floor(u);
u -= ui;
set_four_ipo(u, tu, lt->typeu);
@@ -317,8 +360,7 @@ void calc_latt_deform(float *co)
}
if(lt->pntsv>1) {
- calc_lat_fudu(lt->flag, lt->pntsv, &fu, &du);
- v= (vec[1]-fu)/du;
+ v= (vec[1]-lt->fv)/lt->dv;
vi= (int)floor(v);
v -= vi;
set_four_ipo(v, tv, lt->typev);
@@ -329,8 +371,7 @@ void calc_latt_deform(float *co)
}
if(lt->pntsw>1) {
- calc_lat_fudu(lt->flag, lt->pntsw, &fu, &du);
- w= (vec[2]-fu)/du;
+ w= (vec[2]-lt->fw)/lt->dw;
wi= (int)floor(w);
w -= wi;
set_four_ipo(w, tw, lt->typew);
@@ -568,7 +609,7 @@ int object_deform_mball(Object *ob)
}
}
-BPoint *latt_bp(Lattice *lt, int u, int v, int w)
+static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
{
return lt->def+ u + v*lt->pntsu + w*lt->pntsu*lt->pntsv;
}
@@ -633,3 +674,61 @@ void outside_lattice(Lattice *lt)
}
}
+
+float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]
+{
+ Lattice *lt = (G.obedit==ob)?editLatt:ob->data;
+ int i, numVerts = *numVerts_r = lt->pntsu*lt->pntsv*lt->pntsw;
+ float (*vertexCos)[3] = MEM_mallocN(sizeof(*vertexCos)*numVerts,"lt_vcos");
+
+ for (i=0; i<numVerts; i++) {
+ VECCOPY(vertexCos[i], lt->def[i].vec);
+ }
+
+ return vertexCos;
+}
+
+void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3])
+{
+ Lattice *lt = ob->data;
+ int i, numVerts = lt->pntsu*lt->pntsv*lt->pntsw;
+
+ for (i=0; i<numVerts; i++) {
+ VECCOPY(lt->def[i].vec, vertexCos[i]);
+ }
+}
+
+void lattice_calc_modifiers(Object *ob)
+{
+ float (*vertexCos)[3] = NULL;
+ ModifierData *md = modifiers_getVirtualModifierList(ob);
+ int numVerts, editmode = G.obedit==ob;
+
+ freedisplist(&ob->disp);
+
+ if (!editmode) {
+ do_latt_key(ob->data);
+ }
+
+ for (; md; md=md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (!(md->mode&(1<<0))) continue;
+ if (editmode && !(md->mode&eModifierMode_Editmode)) continue;
+ if (mti->isDisabled && mti->isDisabled(md)) continue;
+ if (mti->type!=eModifierTypeType_OnlyDeform) continue;
+
+ if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts);
+ mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
+ }
+
+ if (vertexCos) {
+ DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
+ dl->type = DL_VERTS;
+ dl->parts = 1;
+ dl->nr = numVerts;
+ dl->verts = (float*) vertexCos;
+
+ BLI_addtail(&ob->disp, dl);
+ }
+}