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:
authorArystanbek Dyussenov <arystan.d@gmail.com>2010-09-04 22:49:07 +0400
committerArystanbek Dyussenov <arystan.d@gmail.com>2010-09-04 22:49:07 +0400
commit90b464d3728d9ed8ec26fdf59058d236b99dbcd9 (patch)
treee88cab4fb1358e962b19f658064ca8c9f8d29f5b /source/blender/blenkernel/intern/lattice.c
parent08d02dd04d836976b25793bb1d4c6a86b3f924c7 (diff)
parentb0b787ef38f9947b3176642556f5282eb3518f69 (diff)
COLLADA branch: merge from trunk -r 28015:31610.soc-2009-chingachgook
Diffstat (limited to 'source/blender/blenkernel/intern/lattice.c')
-rw-r--r--source/blender/blenkernel/intern/lattice.c267
1 files changed, 159 insertions, 108 deletions
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index b7003f45626..1390f0dbd56 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -44,6 +44,7 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
#include "DNA_lattice_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
@@ -59,6 +60,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_utildefines.h"
+#include "BKE_deform.h"
//XXX #include "BIF_editdeform.h"
@@ -173,7 +175,7 @@ void resizelattice(Lattice *lt, int uNew, int vNew, int wNew, Object *ltOb)
bp= lt->def;
for (i=0; i<lt->pntsu*lt->pntsv*lt->pntsw; i++,bp++) {
- VECCOPY(bp->vec, vertexCos[i]);
+ copy_v3_v3(bp->vec, vertexCos[i]);
}
MEM_freeN(vertexCos);
@@ -223,8 +225,12 @@ void free_lattice(Lattice *lt)
if(lt->def) MEM_freeN(lt->def);
if(lt->dvert) free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
if(lt->editlatt) {
- if(lt->editlatt->def) MEM_freeN(lt->editlatt->def);
- if(lt->editlatt->dvert) free_dverts(lt->editlatt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
+ Lattice *editlt= lt->editlatt->latt;
+
+ if(editlt->def) MEM_freeN(editlt->def);
+ if(editlt->dvert) free_dverts(editlt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
+
+ MEM_freeN(editlt);
MEM_freeN(lt->editlatt);
}
}
@@ -293,7 +299,7 @@ void init_latt_deform(Object *oblatt, Object *ob)
float fu, fv, fw;
int u, v, w;
- if(lt->editlatt) lt= lt->editlatt;
+ if(lt->editlatt) lt= lt->editlatt->latt;
bp = lt->def;
fp= lt->latticedata= MEM_mallocN(sizeof(float)*3*lt->pntsu*lt->pntsv*lt->pntsw, "latticedata");
@@ -338,19 +344,29 @@ void calc_latt_deform(Object *ob, float *co, float weight)
{
Lattice *lt= ob->data;
float u, v, w, tu[4], tv[4], tw[4];
- float *fpw, *fpv, *fpu, vec[3];
+ float vec[3];
+ int idx_w, idx_v, idx_u;
int ui, vi, wi, uu, vv, ww;
-
- if(lt->editlatt) lt= lt->editlatt;
+
+ /* vgroup influence */
+ int defgroup_nr= -1;
+ float co_prev[3], weight_blend= 0.0f;
+ MDeformVert *dvert= lattice_get_deform_verts(ob);
+
+
+ if(lt->editlatt) lt= lt->editlatt->latt;
if(lt->latticedata==NULL) return;
-
+
+ if(lt->vgroup[0] && dvert) {
+ defgroup_nr= defgroup_name_index(ob, lt->vgroup);
+ copy_v3_v3(co_prev, co);
+ }
+
/* co is in local coords, treat with latmat */
-
- VECCOPY(vec, co);
- mul_m4_v3(lt->latmat, vec);
-
+ mul_v3_m4v3(vec, lt->latmat, co);
+
/* u v w coords */
-
+
if(lt->pntsu>1) {
u= (vec[0]-lt->fu)/lt->du;
ui= (int)floor(u);
@@ -361,7 +377,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
tu[0]= tu[2]= tu[3]= 0.0; tu[1]= 1.0;
ui= 0;
}
-
+
if(lt->pntsv>1) {
v= (vec[1]-lt->fv)/lt->dv;
vi= (int)floor(v);
@@ -372,7 +388,7 @@ void calc_latt_deform(Object *ob, float *co, float weight)
tv[0]= tv[2]= tv[3]= 0.0; tv[1]= 1.0;
vi= 0;
}
-
+
if(lt->pntsw>1) {
w= (vec[2]-lt->fw)/lt->dw;
wi= (int)floor(w);
@@ -383,53 +399,58 @@ void calc_latt_deform(Object *ob, float *co, float weight)
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= lt->latticedata + 3*ww*lt->pntsu*lt->pntsv;
- else fpw= lt->latticedata + 3*(lt->pntsw-1)*lt->pntsu*lt->pntsv;
+ if(ww<lt->pntsw) idx_w= ww*lt->pntsu*lt->pntsv;
+ else idx_w= (lt->pntsw-1)*lt->pntsu*lt->pntsv;
}
- else fpw= lt->latticedata;
-
+ else idx_w= 0;
+
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;
+ if(vv<lt->pntsv) idx_v= idx_w + vv*lt->pntsu;
+ else idx_v= idx_w + (lt->pntsv-1)*lt->pntsu;
}
- else fpv= fpw;
-
+ else idx_v= idx_w;
+
for(uu= ui-1; uu<=ui+2; uu++) {
u= weight*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);
+ if(uu<lt->pntsu) idx_u= idx_v + uu;
+ else idx_u= idx_v + (lt->pntsu-1);
}
- else fpu= fpv;
-
- co[0]+= u*fpu[0];
- co[1]+= u*fpu[1];
- co[2]+= u*fpu[2];
+ else idx_u= idx_v;
+
+ madd_v3_v3fl(co, &lt->latticedata[idx_u * 3], u);
+
+ if(defgroup_nr != -1)
+ weight_blend += (u * defvert_find_weight(dvert + idx_u, defgroup_nr));
}
}
}
}
}
}
+
+ if(defgroup_nr != -1)
+ interp_v3_v3v3(co, co_prev, co, weight_blend);
+
}
void end_latt_deform(Object *ob)
{
Lattice *lt= ob->data;
- if(lt->editlatt) lt= lt->editlatt;
+ if(lt->editlatt) lt= lt->editlatt->latt;
if(lt->latticedata)
MEM_freeN(lt->latticedata);
@@ -457,7 +478,9 @@ static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc
invert_m4_m4(par->imat, par->obmat);
mul_v3_m4v3(cd->dloc, par->imat, ob->obmat[3]);
}
- else cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f;
+ else {
+ cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f;
+ }
cd->no_rot_axis= 0;
}
@@ -481,7 +504,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
else ctime1= ctime;
/* vec needs 4 items */
- if(where_on_path(ob, ctime1, vec, dir, quat, radius)) {
+ if(where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
if(cycl==0) {
Path *path= cu->path;
@@ -490,16 +513,17 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
if(ctime < 0.0) {
sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec);
mul_v3_fl(dvec, ctime*(float)path->len);
- VECADD(vec, vec, dvec);
- if(quat) QUATCOPY(quat, path->data[0].quat);
+ add_v3_v3(vec, dvec);
+ if(quat) copy_qt_qt(quat, path->data[0].quat);
if(radius) *radius= path->data[0].radius;
}
else if(ctime > 1.0) {
sub_v3_v3v3(dvec, path->data[path->len-1].vec, path->data[path->len-2].vec);
mul_v3_fl(dvec, (ctime-1.0)*(float)path->len);
- VECADD(vec, vec, dvec);
- if(quat) QUATCOPY(quat, path->data[path->len-1].quat);
+ add_v3_v3(vec, dvec);
+ if(quat) copy_qt_qt(quat, path->data[path->len-1].quat);
if(radius) *radius= path->data[path->len-1].radius;
+ /* weight - not used but could be added */
}
}
return 1;
@@ -590,7 +614,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
/* this is not exactly the same as 2.4x, since the axis is having rotation removed rather then
* changing the axis before calculating the tilt but serves much the same purpose */
float dir_flat[3]={0,0,0}, q[4];
- VECCOPY(dir_flat, dir);
+ copy_v3_v3(dir_flat, dir);
dir_flat[cd->no_rot_axis-1]= 0.0f;
normalize_v3(dir);
@@ -668,11 +692,11 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C
mul_qt_v3(quat, cent);
/* translation */
- VECADD(co, cent, loc);
+ add_v3_v3v3(co, cent, loc);
if(quatp)
- QUATCOPY(quatp, quat);
-
+ copy_qt_qt(quatp, quat);
+
return 1;
}
return 0;
@@ -693,7 +717,18 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh
cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0);
-
+
+ /* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */
+ if(defaxis < 3) {
+ cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
+ cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
+ }
+ else {
+ /* negative, these bounds give a good rest position */
+ cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= -1.0f;
+ cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 0.0f;
+ }
+
/* check whether to use vertex groups (only possible if target is a Mesh)
* we want either a Mesh with no derived data, or derived data with
* deformverts
@@ -708,62 +743,84 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh
use_vgroups = 0;
if(vgroup && vgroup[0] && use_vgroups) {
- bDeformGroup *curdef;
Mesh *me= target->data;
- int index;
-
- /* find the group (weak loop-in-loop) */
- for(index = 0, curdef = target->defbase.first; curdef;
- curdef = curdef->next, index++)
- if (!strcmp(curdef->name, vgroup))
- break;
+ int index= defgroup_name_index(target, vgroup);
- if(curdef && (me->dvert || dm)) {
+ if(index != -1 && (me->dvert || dm)) {
MDeformVert *dvert = me->dvert;
float vec[3];
- int j;
-
- INIT_MINMAX(cd.dmin, cd.dmax);
-
- for(a = 0; a < numVerts; a++, dvert++) {
- if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+ float weight;
+
- for(j = 0; j < dvert->totweight; j++) {
- if(dvert->dw[j].def_nr == index) {
+ if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
+ /* dummy bounds */
+ cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
+ cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
+
+ dvert = me->dvert;
+ for(a = 0; a < numVerts; a++, dvert++) {
+ if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+ weight= defvert_find_weight(dvert, index);
+
+ if(weight > 0.0f) {
mul_m4_v3(cd.curvespace, vertexCos[a]);
- DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
- break;
+ copy_v3_v3(vec, vertexCos[a]);
+ calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
+ interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
+ mul_m4_v3(cd.objectspace, vertexCos[a]);
}
}
}
-
- dvert = me->dvert;
- for(a = 0; a < numVerts; a++, dvert++) {
- if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
-
- for(j = 0; j < dvert->totweight; j++) {
- if(dvert->dw[j].def_nr == index) {
- VECCOPY(vec, vertexCos[a]);
+ else {
+ /* set mesh min/max bounds */
+ INIT_MINMAX(cd.dmin, cd.dmax);
+
+ for(a = 0; a < numVerts; a++, dvert++) {
+ if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+
+ if(defvert_find_weight(dvert, index) > 0.0f) {
+ mul_m4_v3(cd.curvespace, vertexCos[a]);
+ DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+ }
+ }
+
+ dvert = me->dvert;
+ for(a = 0; a < numVerts; a++, dvert++) {
+ if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+
+ weight= defvert_find_weight(dvert, index);
+
+ if(weight > 0.0f) {
+ copy_v3_v3(vec, vertexCos[a]);
calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
- interp_v3_v3v3(vertexCos[a], vertexCos[a], vec,
- dvert->dw[j].weight);
+ interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
mul_m4_v3(cd.objectspace, vertexCos[a]);
- break;
}
}
}
}
- } else {
- INIT_MINMAX(cd.dmin, cd.dmax);
-
- for(a = 0; a < numVerts; a++) {
- mul_m4_v3(cd.curvespace, vertexCos[a]);
- DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+ }
+ else {
+ if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
+ for(a = 0; a < numVerts; a++) {
+ mul_m4_v3(cd.curvespace, vertexCos[a]);
+ calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
+ mul_m4_v3(cd.objectspace, vertexCos[a]);
+ }
}
-
- for(a = 0; a < numVerts; a++) {
- calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
- mul_m4_v3(cd.objectspace, vertexCos[a]);
+ else {
+ /* set mesh min max bounds */
+ INIT_MINMAX(cd.dmin, cd.dmax);
+
+ for(a = 0; a < numVerts; a++) {
+ mul_m4_v3(cd.curvespace, vertexCos[a]);
+ DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+ }
+
+ for(a = 0; a < numVerts; a++) {
+ calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
+ mul_m4_v3(cd.objectspace, vertexCos[a]);
+ }
}
}
cu->flag = flag;
@@ -785,8 +842,8 @@ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco
init_curve_deform(cuOb, target, &cd, 0); /* 0 no dloc */
cd.no_rot_axis= no_rot_axis; /* option to only rotate for XY, for example */
- VECCOPY(cd.dmin, orco);
- VECCOPY(cd.dmax, orco);
+ copy_v3_v3(cd.dmin, orco);
+ copy_v3_v3(cd.dmax, orco);
mul_m4_v3(cd.curvespace, vec);
@@ -828,26 +885,20 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
use_vgroups = 0;
if(vgroup && vgroup[0] && use_vgroups) {
- bDeformGroup *curdef;
Mesh *me = target->data;
- int index = 0;
-
- /* find the group (weak loop-in-loop) */
- for(curdef = target->defbase.first; curdef;
- curdef = curdef->next, index++)
- if(!strcmp(curdef->name, vgroup)) break;
+ int index = defgroup_name_index(target, vgroup);
+ float weight;
- if(curdef && (me->dvert || dm)) {
+ if(index >= 0 && (me->dvert || dm)) {
MDeformVert *dvert = me->dvert;
- int j;
for(a = 0; a < numVerts; a++, dvert++) {
if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
- for(j = 0; j < dvert->totweight; j++) {
- if (dvert->dw[j].def_nr == index) {
- calc_latt_deform(laOb, vertexCos[a], dvert->dw[j].weight);
- }
- }
+
+ weight= defvert_find_weight(dvert, index);
+
+ if(weight > 0.0f)
+ calc_latt_deform(laOb, vertexCos[a], weight);
}
}
} else {
@@ -858,12 +909,12 @@ void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm,
end_latt_deform(laOb);
}
-int object_deform_mball(Object *ob)
+int object_deform_mball(Object *ob, ListBase *dispbase)
{
if(ob->parent && ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
DispList *dl;
- for (dl=ob->disp.first; dl; dl=dl->next) {
+ for (dl=dispbase->first; dl; dl=dl->next) {
lattice_deform_verts(ob->parent, ob, NULL,
(float(*)[3]) dl->verts, dl->nr, NULL);
}
@@ -955,13 +1006,13 @@ float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]
int i, numVerts;
float (*vertexCos)[3];
- if(lt->editlatt) lt= lt->editlatt;
+ if(lt->editlatt) lt= lt->editlatt->latt;
numVerts = *numVerts_r = lt->pntsu*lt->pntsv*lt->pntsw;
vertexCos = MEM_mallocN(sizeof(*vertexCos)*numVerts,"lt_vcos");
for (i=0; i<numVerts; i++) {
- VECCOPY(vertexCos[i], lt->def[i].vec);
+ copy_v3_v3(vertexCos[i], lt->def[i].vec);
}
return vertexCos;
@@ -973,7 +1024,7 @@ void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3])
int i, numVerts = lt->pntsu*lt->pntsv*lt->pntsw;
for (i=0; i<numVerts; i++) {
- VECCOPY(lt->def[i].vec, vertexCos[i]);
+ copy_v3_v3(lt->def[i].vec, vertexCos[i]);
}
}
@@ -1019,7 +1070,7 @@ struct MDeformVert* lattice_get_deform_verts(struct Object *oblatt)
if(oblatt->type == OB_LATTICE)
{
Lattice *lt = (Lattice*)oblatt->data;
- if(lt->editlatt) lt= lt->editlatt;
+ if(lt->editlatt) lt= lt->editlatt->latt;
return lt->dvert;
}