- readded DL_VERTS type to store lattice deformed verts
- new feature, twiddled with lattice resizing to try to maintain existing vertex changes... much nicer than just resetting the lattice if you decide you need more detail in the lattice. - modifiers work with lattices now. yes, that does mean you can make a chain of lattices effecting each other 8 miles long. - some cleanup of softbody code, was rather splintered and call path was twisted and confusing. reworked main object step routine to do things in a more obvious and consistent manner and without duplicate code - added ob->softflag OB_SB_RESET instead of sbObjectReset call - modifier changes reset softbody now - moved curve_getVertexCos/curve_applyVertexCos into curve.c - update curve modifier eval to work with virtual modifiers - update modifier apply to work with curves/surfs - update make parent to also recalc object data NOTE: Although you can turn SB on for curve/font objects at the moment it doesn't really work because they call deform in multiple steps and this confuses SB. Not sure how to deal with atm.
This commit is contained in:
@@ -86,5 +86,8 @@ void sethandlesNurb(short code);
|
||||
void swapdata(void *adr1, void *adr2, int len);
|
||||
void switchdirectionNurb( struct Nurb *nu);
|
||||
|
||||
float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3];
|
||||
void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#define DL_INDEX3 4
|
||||
#define DL_INDEX4 5
|
||||
#define DL_VERTCOL 6
|
||||
#define DL_VERTS 7
|
||||
|
||||
/* dl->flag */
|
||||
#define DL_CYCL_U 1
|
||||
|
||||
@@ -41,7 +41,7 @@ struct BPoint;
|
||||
extern struct Lattice *editLatt;
|
||||
|
||||
|
||||
void resizelattice(struct Lattice *lt);
|
||||
void resizelattice(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
|
||||
struct Lattice *add_lattice(void);
|
||||
struct Lattice *copy_lattice(struct Lattice *lt);
|
||||
void free_lattice(struct Lattice *lt);
|
||||
@@ -51,11 +51,13 @@ void init_latt_deform(struct Object *oblatt, struct Object *ob);
|
||||
void calc_latt_deform(float *co);
|
||||
void end_latt_deform(void);
|
||||
int object_deform_mball(struct Object *ob);
|
||||
struct BPoint *latt_bp(struct Lattice *lt, int u, int v, int w);
|
||||
void outside_lattice(struct Lattice *lt);
|
||||
void curve_deform_verts(struct Object *cuOb, struct Object *target, float (*vertexCos)[3], int numVerts);
|
||||
void lattice_deform_verts(struct Object *laOb, struct Object *target, float (*vertexCos)[3], int numVerts);
|
||||
void armature_deform_verts(struct Object *armOb, struct Object *target, float (*vertexCos)[3], int numVerts);
|
||||
float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3];
|
||||
void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]);
|
||||
void lattice_calc_modifiers(struct Object *ob);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,19 +34,6 @@
|
||||
#ifndef BKE_SOFTBODY_H
|
||||
#define BKE_SOFTBODY_H
|
||||
|
||||
typedef struct BodyPoint {
|
||||
float origS[3], origE[3], origT[3], pos[3], vec[3], force[3];
|
||||
float weight, goal;
|
||||
float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
|
||||
int nofsprings; int *springs;
|
||||
float contactfrict;
|
||||
} BodyPoint;
|
||||
|
||||
typedef struct BodySpring {
|
||||
int v1, v2;
|
||||
float len, strength;
|
||||
} BodySpring;
|
||||
|
||||
struct Object;
|
||||
struct SoftBody;
|
||||
|
||||
@@ -56,16 +43,11 @@ extern struct SoftBody *sbNew(void);
|
||||
/* frees internal data and softbody itself */
|
||||
extern void sbFree(struct SoftBody *sb);
|
||||
|
||||
/* go one step in simulation, copy result in vertexCos for meshes, or
|
||||
* directly for lattices.
|
||||
*/
|
||||
extern void sbObjectStep(struct Object *ob, float framnr, float (*vertexCos)[3]);
|
||||
/* do one simul step, reading and writing vertex locs from given array */
|
||||
extern void sbObjectStep(struct Object *ob, float framnr, float (*vertexCos)[3], int numVerts);
|
||||
|
||||
/* makes totally fresh start situation, resets time */
|
||||
extern void sbObjectToSoftbody(struct Object *ob, float (*vertexCos)[3]);
|
||||
|
||||
/* resets all motion and time */
|
||||
extern void sbObjectReset(struct Object *ob, float (*vertexCos)[3]);
|
||||
extern void sbObjectToSoftbody(struct Object *ob);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2411,3 +2411,57 @@ void switchdirectionNurb(Nurb *nu)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3]
|
||||
{
|
||||
int i, numVerts = *numVerts_r = count_curveverts(lb);
|
||||
float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
|
||||
Nurb *nu;
|
||||
|
||||
co = cos[0];
|
||||
for (nu=lb->first; nu; nu=nu->next) {
|
||||
if ((nu->type & 7)==CU_BEZIER) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for (i=0; i<nu->pntsu; i++,bezt++) {
|
||||
VECCOPY(co, bezt->vec[0]); co+=3;
|
||||
VECCOPY(co, bezt->vec[1]); co+=3;
|
||||
VECCOPY(co, bezt->vec[2]); co+=3;
|
||||
}
|
||||
} else {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
|
||||
VECCOPY(co, bp->vec); co+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cos;
|
||||
}
|
||||
|
||||
void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
|
||||
{
|
||||
float *co = vertexCos[0];
|
||||
Nurb *nu;
|
||||
int i;
|
||||
|
||||
for (nu=lb->first; nu; nu=nu->next) {
|
||||
if ((nu->type & 7)==CU_BEZIER) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for (i=0; i<nu->pntsu; i++,bezt++) {
|
||||
VECCOPY(bezt->vec[0], co); co+=3;
|
||||
VECCOPY(bezt->vec[1], co); co+=3;
|
||||
VECCOPY(bezt->vec[2], co); co+=3;
|
||||
}
|
||||
} else {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
|
||||
VECCOPY(bp->vec, co); co+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1417,65 +1417,13 @@ void makeDispListMBall(Object *ob)
|
||||
boundbox_displist(ob);
|
||||
}
|
||||
|
||||
float (*curve_getVertexCos(Curve *cu, ListBase *lb, int *numVerts_r))[3]
|
||||
{
|
||||
int i, numVerts = *numVerts_r = count_curveverts(lb);
|
||||
float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
|
||||
Nurb *nu;
|
||||
|
||||
co = cos[0];
|
||||
for (nu=lb->first; nu; nu=nu->next) {
|
||||
if ((nu->type & 7)==CU_BEZIER) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for (i=0; i<nu->pntsu; i++,bezt++) {
|
||||
VECCOPY(co, bezt->vec[0]); co+=3;
|
||||
VECCOPY(co, bezt->vec[1]); co+=3;
|
||||
VECCOPY(co, bezt->vec[2]); co+=3;
|
||||
}
|
||||
} else {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
|
||||
VECCOPY(co, bp->vec); co+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cos;
|
||||
}
|
||||
|
||||
void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
|
||||
{
|
||||
float *co = vertexCos[0];
|
||||
Nurb *nu;
|
||||
int i;
|
||||
|
||||
for (nu=lb->first; nu; nu=nu->next) {
|
||||
if ((nu->type & 7)==CU_BEZIER) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for (i=0; i<nu->pntsu; i++,bezt++) {
|
||||
VECCOPY(bezt->vec[0], co); co+=3;
|
||||
VECCOPY(bezt->vec[1], co); co+=3;
|
||||
VECCOPY(bezt->vec[2], co); co+=3;
|
||||
}
|
||||
} else {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for (i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
|
||||
VECCOPY(bp->vec, co); co+=3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode)
|
||||
{
|
||||
ModifierData *md, *preTesselatePoint;
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob);
|
||||
ModifierData *preTesselatePoint;
|
||||
|
||||
preTesselatePoint = NULL;
|
||||
for (md=ob->modifiers.first; md; md=md->next) {
|
||||
for (; md; md=md->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if (!(md->mode&(1<<forRender))) continue;
|
||||
@@ -1493,13 +1441,14 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed
|
||||
void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
|
||||
{
|
||||
int editmode = (!forRender && ob==G.obedit);
|
||||
ModifierData *md, *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob);
|
||||
ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
|
||||
int numVerts = 0;
|
||||
float (*originalVerts)[3] = NULL;
|
||||
float (*deformedVerts)[3] = NULL;
|
||||
|
||||
if (preTesselatePoint) {
|
||||
for (md=ob->modifiers.first; md; md=md->next) {
|
||||
for (; md; md=md->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
if (!(md->mode&(1<<forRender))) continue;
|
||||
@@ -1516,8 +1465,6 @@ void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float (
|
||||
if (md==preTesselatePoint)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
md = ob->modifiers.first;
|
||||
}
|
||||
|
||||
if (deformedVerts) {
|
||||
@@ -1532,13 +1479,12 @@ void curve_calc_modifiers_pre(Object *ob, ListBase *nurb, int forRender, float (
|
||||
void curve_calc_modifiers_post(Object *ob, ListBase *nurb, ListBase *dispbase, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
|
||||
{
|
||||
int editmode = (!forRender && ob==G.obedit);
|
||||
ModifierData *md, *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
|
||||
ModifierData *md = modifiers_getVirtualModifierList(ob);
|
||||
ModifierData *preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
|
||||
DispList *dl;
|
||||
|
||||
if (preTesselatePoint) {
|
||||
md = preTesselatePoint->next;
|
||||
} else {
|
||||
md = ob->modifiers.first;
|
||||
}
|
||||
|
||||
for (; md; md=md->next) {
|
||||
|
||||
@@ -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(<Ob->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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1172,7 +1172,7 @@ static void softbodyModifier_deformVerts(ModifierData *md, Object *ob, void *der
|
||||
{
|
||||
SoftbodyModifierData *hmd = (SoftbodyModifierData*) md;
|
||||
|
||||
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos);
|
||||
sbObjectStep(ob, (float)G.scene->r.cfra, vertexCos, numVerts);
|
||||
}
|
||||
|
||||
/***/
|
||||
|
||||
@@ -1762,6 +1762,9 @@ void object_handle_update(Object *ob)
|
||||
else if(ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
|
||||
makeDispListCurveTypes(ob, 0);
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
lattice_calc_modifiers(ob);
|
||||
}
|
||||
else if(ob->type==OB_ARMATURE) {
|
||||
/* this actually only happens for reading old files... */
|
||||
if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC))
|
||||
|
||||
@@ -85,6 +85,21 @@ extern int get_defgroup_num (Object *ob, bDeformGroup *dg);
|
||||
|
||||
|
||||
/* ********** soft body engine ******* */
|
||||
|
||||
typedef struct BodyPoint {
|
||||
float origS[3], origE[3], origT[3], pos[3], vec[3], force[3];
|
||||
float weight, goal;
|
||||
float prevpos[3], prevvec[3], prevdx[3], prevdv[3]; /* used for Heun integration */
|
||||
int nofsprings; int *springs;
|
||||
float contactfrict;
|
||||
} BodyPoint;
|
||||
|
||||
typedef struct BodySpring {
|
||||
int v1, v2;
|
||||
float len, strength;
|
||||
} BodySpring;
|
||||
|
||||
|
||||
#define SOFTGOALSNAP 0.999f
|
||||
// if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp
|
||||
// removes *unnecessary* stiffnes from ODE system
|
||||
@@ -179,12 +194,10 @@ static void add_mesh_quad_diag_springs(Object *ob)
|
||||
bs->v1= mface->v1;
|
||||
bs->v2= mface->v3;
|
||||
bs->strength= 1.0;
|
||||
bs->len= VecLenf( (bp+bs->v1)->origS, (bp+bs->v2)->origS);
|
||||
bs++;
|
||||
bs->v1= mface->v2;
|
||||
bs->v2= mface->v4;
|
||||
bs->strength= 1.0;
|
||||
bs->len= VecLenf( (bp+bs->v1)->origS, (bp+bs->v2)->origS);
|
||||
bs++;
|
||||
|
||||
}
|
||||
@@ -245,10 +258,10 @@ static void build_bps_springlist(Object *ob)
|
||||
|
||||
|
||||
/* creates new softbody if didn't exist yet, makes new points and springs arrays */
|
||||
/* called in mesh_to_softbody */
|
||||
static void renew_softbody(Object *ob, int totpoint, int totspring)
|
||||
{
|
||||
SoftBody *sb;
|
||||
int i;
|
||||
|
||||
if(ob->soft==NULL) ob->soft= sbNew();
|
||||
else free_softbody_intern(ob->soft);
|
||||
@@ -261,6 +274,24 @@ static void renew_softbody(Object *ob, int totpoint, int totspring)
|
||||
sb->bpoint= MEM_mallocN( totpoint*sizeof(BodyPoint), "bodypoint");
|
||||
if(totspring)
|
||||
sb->bspring= MEM_mallocN( totspring*sizeof(BodySpring), "bodyspring");
|
||||
|
||||
/* initialise BodyPoint array */
|
||||
for (i=0; i<totpoint; i++) {
|
||||
BodyPoint *bp = &sb->bpoint[i];
|
||||
|
||||
bp->weight= 1.0;
|
||||
if(ob->softflag & OB_SB_GOAL) {
|
||||
bp->goal= ob->soft->defgoal;
|
||||
}
|
||||
else {
|
||||
bp->goal= 0.0f;
|
||||
/* so this will definily be below SOFTGOALSNAP */
|
||||
}
|
||||
|
||||
bp->nofsprings= 0;
|
||||
bp->springs= NULL;
|
||||
bp->contactfrict = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -723,94 +754,9 @@ static void interpolate_exciter(Object *ob, int timescale, int time)
|
||||
/* ************ convertors ********** */
|
||||
|
||||
/* for each object type we need;
|
||||
- xxxx_to_softbody(Object *ob) : a full (new) copy
|
||||
- xxxx_update_softbody(Object *ob) : update refreshes current positions
|
||||
- softbody_to_xxxx(Object *ob) : after simulation, copy vertex locations back
|
||||
- xxxx_to_softbody(Object *ob) : a full (new) copy, creates SB geometry
|
||||
*/
|
||||
|
||||
/* helper call */
|
||||
static int object_has_edges(Object *ob)
|
||||
{
|
||||
if(ob->type==OB_MESH) {
|
||||
Mesh *me= ob->data;
|
||||
if(me->medge) return 1;
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* helper call */
|
||||
static void set_body_point(Object *ob, BodyPoint *bp, float *vec)
|
||||
{
|
||||
VECCOPY(bp->pos, vec);
|
||||
Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords
|
||||
VECCOPY(bp->origS, bp->pos);
|
||||
VECCOPY(bp->origE, bp->pos);
|
||||
VECCOPY(bp->origT, bp->pos);
|
||||
|
||||
bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0;
|
||||
bp->weight= 1.0;
|
||||
if(ob->softflag & OB_SB_GOAL) {
|
||||
bp->goal= ob->soft->defgoal;
|
||||
}
|
||||
else {
|
||||
bp->goal= 0.0f;
|
||||
/* so this will definily be below SOFTGOALSNAP */
|
||||
}
|
||||
|
||||
bp->nofsprings= 0;
|
||||
bp->springs= NULL;
|
||||
bp->contactfrict = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
/* copy original (new) situation in softbody, as result of matrices or deform */
|
||||
/* is assumed to enter function with ob->soft, but can be without points */
|
||||
static void mesh_update_softbody(Object *ob, float (*vertexCos)[3])
|
||||
{
|
||||
Mesh *me= ob->data;
|
||||
BodyPoint *bp;
|
||||
int a;
|
||||
|
||||
/* possible after a file read... */
|
||||
if(ob->soft->bpoint==NULL) sbObjectToSoftbody(ob, NULL);
|
||||
|
||||
if(me->totvert) {
|
||||
bp= ob->soft->bpoint;
|
||||
for(a=0; a<me->totvert; a++, bp++) {
|
||||
VECCOPY(bp->origS, bp->origE);
|
||||
if (vertexCos) {
|
||||
VECCOPY(bp->origE, vertexCos[a]);
|
||||
} else {
|
||||
VECCOPY(bp->origE, me->mvert[a].co);
|
||||
}
|
||||
Mat4MulVecfl(ob->obmat, bp->origE);
|
||||
VECCOPY(bp->origT, bp->origE);
|
||||
}
|
||||
|
||||
if(ob->softflag & OB_SB_EDGES) {
|
||||
|
||||
/* happens when in UI edges was set */
|
||||
if(ob->soft->bspring==NULL)
|
||||
if(object_has_edges(ob)) sbObjectToSoftbody(ob, NULL);
|
||||
|
||||
/* hrms .. do springs alter their lenght ? (yes, mesh keys would (ton))
|
||||
if(medge) {
|
||||
bs= ob->soft->bspring;
|
||||
bp= ob->soft->bpoint;
|
||||
for(a=0; (a<me->totedge && a < ob->soft->totspring ); a++, medge++, bs++) {
|
||||
bs->len= VecLenf( (bp+bs->v1)->origE, (bp+bs->v2)->origE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex, float *target)
|
||||
/* result 0 on success, else indicates error number
|
||||
-- kind of *inverse* result defintion,
|
||||
@@ -837,7 +783,7 @@ static void get_scalar_from_vertexgroup(Object *ob, int vertID, short groupindex
|
||||
}
|
||||
|
||||
/* makes totally fresh start situation */
|
||||
static void mesh_to_softbody(Object *ob, float (*vertexCos)[3])
|
||||
static void mesh_to_softbody(Object *ob)
|
||||
{
|
||||
SoftBody *sb;
|
||||
Mesh *me= ob->data;
|
||||
@@ -859,12 +805,6 @@ static void mesh_to_softbody(Object *ob, float (*vertexCos)[3])
|
||||
goalfac= ABS(sb->maxgoal - sb->mingoal);
|
||||
|
||||
for(a=0; a<me->totvert; a++, bp++) {
|
||||
if (vertexCos) {
|
||||
set_body_point(ob, bp, vertexCos[a]);
|
||||
} else {
|
||||
set_body_point(ob, bp, me->mvert[a].co);
|
||||
}
|
||||
|
||||
/* get scalar values needed *per vertex* from vertex group functions,
|
||||
so we can *paint* them nicly ..
|
||||
they are normalized [0.0..1.0] so may be we need amplitude for scale
|
||||
@@ -891,12 +831,10 @@ static void mesh_to_softbody(Object *ob, float (*vertexCos)[3])
|
||||
if (ob->softflag & OB_SB_EDGES) {
|
||||
if(medge) {
|
||||
bs= sb->bspring;
|
||||
bp= sb->bpoint;
|
||||
for(a=me->totedge; a>0; a--, medge++, bs++) {
|
||||
bs->v1= medge->v1;
|
||||
bs->v2= medge->v2;
|
||||
bs->strength= 1.0;
|
||||
bs->len= VecLenf( (bp+bs->v1)->origS, (bp+bs->v2)->origS);
|
||||
}
|
||||
|
||||
|
||||
@@ -911,19 +849,6 @@ static void mesh_to_softbody(Object *ob, float (*vertexCos)[3])
|
||||
|
||||
}
|
||||
|
||||
/* copies current sofbody position in mesh, so do this within modifier stacks! */
|
||||
static void softbody_to_mesh(Object *ob, float (*vertexCos)[3])
|
||||
{
|
||||
Mesh *me= ob->data;
|
||||
BodyPoint *bp= ob->soft->bpoint;
|
||||
int a;
|
||||
|
||||
for(a=me->totvert; a>0; a--, bp++, vertexCos++) {
|
||||
VECCOPY(vertexCos[0], bp->pos);
|
||||
Mat4MulVecfl(ob->imat, vertexCos[0]); // softbody is in global coords
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
|
||||
{
|
||||
@@ -1021,23 +946,17 @@ static void makelatticesprings(Lattice *lt, BodySpring *bs, int dostiff)
|
||||
/* makes totally fresh start situation */
|
||||
static void lattice_to_softbody(Object *ob)
|
||||
{
|
||||
SoftBody *sb;
|
||||
BodySpring *bs;
|
||||
Lattice *lt= ob->data;
|
||||
BodyPoint *bop;
|
||||
BPoint *bp;
|
||||
int a, totvert, totspring = 0;
|
||||
int totvert, totspring = 0;
|
||||
|
||||
totvert= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
|
||||
if (ob->softflag & OB_SB_EDGES){
|
||||
|
||||
totspring = ((lt->pntsu -1) * lt->pntsv
|
||||
+ (lt->pntsv -1) * lt->pntsu) * lt->pntsw
|
||||
+lt->pntsu*lt->pntsv*(lt->pntsw -1);
|
||||
if (ob->softflag & OB_SB_QUADS){
|
||||
totspring += 4*(lt->pntsu -1) * (lt->pntsv -1) * (lt->pntsw-1);
|
||||
|
||||
totspring += 4*(lt->pntsu -1) * (lt->pntsv -1) * (lt->pntsw-1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1045,110 +964,31 @@ static void lattice_to_softbody(Object *ob)
|
||||
/* renew ends with ob->soft with points and edges, also checks & makes ob->soft */
|
||||
renew_softbody(ob, totvert, totspring);
|
||||
|
||||
/* we always make body points */
|
||||
sb= ob->soft;
|
||||
|
||||
for(a= totvert, bp= lt->def, bop= sb->bpoint; a>0; a--, bp++, bop++) {
|
||||
set_body_point(ob, bop, bp->vec);
|
||||
}
|
||||
|
||||
/* create some helper edges to enable SB lattice to be usefull at all */
|
||||
if (ob->softflag & OB_SB_EDGES){
|
||||
bs = sb->bspring;
|
||||
makelatticesprings(lt,bs,ob->softflag & OB_SB_QUADS);
|
||||
makelatticesprings(lt,ob->soft->bspring,ob->softflag & OB_SB_QUADS);
|
||||
build_bps_springlist(ob); /* link bps to springs */
|
||||
|
||||
/* recalculate lenght since BPoint and Bodypoint obviously can differ */
|
||||
bs= ob->soft->bspring;
|
||||
bop= ob->soft->bpoint;
|
||||
for(a=0; a < totspring ; a++, bs++) {
|
||||
bs->len= VecLenf( (bop+bs->v1)->origE, (bop+bs->v2)->origE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* copies current sofbody position */
|
||||
static void softbody_to_lattice(Object *ob)
|
||||
{
|
||||
SoftBody *sb;
|
||||
Lattice *lt= ob->data;
|
||||
BodyPoint *bop;
|
||||
BPoint *bp;
|
||||
int a, totvert;
|
||||
|
||||
totvert= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
sb= ob->soft;
|
||||
|
||||
for(a= totvert, bp= lt->def, bop= sb->bpoint; a>0; a--, bp++, bop++) {
|
||||
VECCOPY(bp->vec, bop->pos);
|
||||
Mat4MulVecfl(ob->imat, bp->vec); // softbody is in global coords
|
||||
}
|
||||
}
|
||||
|
||||
/* copy original (new) situation in softbody, as result of matrices or deform */
|
||||
/* is assumed to enter function with ob->soft, but can be without points */
|
||||
static void lattice_update_softbody(Object *ob)
|
||||
{
|
||||
Lattice *lt= ob->data;
|
||||
BodyPoint *bop;
|
||||
BPoint *bp;
|
||||
int a, totvert;
|
||||
|
||||
totvert= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
|
||||
/* possible after a file read... */
|
||||
if(ob->soft->bpoint==NULL) sbObjectToSoftbody(ob, NULL);
|
||||
|
||||
for(a= totvert, bp= lt->def, bop= ob->soft->bpoint; a>0; a--, bp++, bop++) {
|
||||
VECCOPY(bop->origS, bop->origE);
|
||||
VECCOPY(bop->origE, bp->vec);
|
||||
Mat4MulVecfl(ob->obmat, bop->origE);
|
||||
VECCOPY(bop->origT, bop->origE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* copies softbody result back in object */
|
||||
/* only used in sbObjectStep() */
|
||||
static void softbody_to_object(Object *ob, float (*vertexCos)[3])
|
||||
static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
|
||||
if(ob->soft==NULL) return;
|
||||
|
||||
BodyPoint *bp= ob->soft->bpoint;
|
||||
int a;
|
||||
|
||||
/* inverse matrix is not uptodate... */
|
||||
Mat4Invert(ob->imat, ob->obmat);
|
||||
|
||||
switch(ob->type) {
|
||||
case OB_MESH:
|
||||
softbody_to_mesh(ob, vertexCos);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
softbody_to_lattice(ob);
|
||||
break;
|
||||
for(a=0; a<numVerts; a++, bp++) {
|
||||
VECCOPY(vertexCos[a], bp->pos);
|
||||
Mat4MulVecfl(ob->imat, vertexCos[a]); // softbody is in global coords
|
||||
}
|
||||
}
|
||||
|
||||
/* copy original (new) situation in softbody, as result of matrices or deform */
|
||||
/* used in sbObjectStep() and sbObjectReset() */
|
||||
/* assumes to have ob->soft, but can be entered without points */
|
||||
static void object_update_softbody(Object *ob, float (*vertexCos)[3])
|
||||
{
|
||||
|
||||
switch(ob->type) {
|
||||
case OB_MESH:
|
||||
mesh_update_softbody(ob, vertexCos);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
lattice_update_softbody(ob);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* return 1 if succesfully baked and applied step */
|
||||
static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3])
|
||||
static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
SoftBody *sb= ob->soft;
|
||||
SBVertex *key0, *key1, *key2, *key3;
|
||||
@@ -1200,7 +1040,7 @@ static int softbody_baked_step(Object *ob, float framenr, float (*vertexCos)[3])
|
||||
bp->pos[2]= data[0]*key0->vec[2] + data[1]*key1->vec[2] + data[2]*key2->vec[2] + data[3]*key3->vec[2];
|
||||
}
|
||||
|
||||
softbody_to_object(ob, vertexCos);
|
||||
softbody_to_object(ob, vertexCos, numVerts);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1293,79 +1133,68 @@ void sbFree(SoftBody *sb)
|
||||
|
||||
|
||||
/* makes totally fresh start situation */
|
||||
void sbObjectToSoftbody(Object *ob, float (*vertexCos)[3])
|
||||
void sbObjectToSoftbody(Object *ob)
|
||||
{
|
||||
ob->softflag |= OB_SB_REDO;
|
||||
}
|
||||
|
||||
static void convert_object_to_sb(Object *ob, int numVerts)
|
||||
{
|
||||
switch(ob->type) {
|
||||
case OB_MESH:
|
||||
mesh_to_softbody(ob, vertexCos);
|
||||
mesh_to_softbody(ob);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
lattice_to_softbody(ob);
|
||||
break;
|
||||
default:
|
||||
renew_softbody(ob, numVerts, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if(ob->soft) ob->soft->ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
|
||||
ob->softflag &= ~OB_SB_REDO;
|
||||
|
||||
/* still need to update to correct vertex locations, happens on next step */
|
||||
ob->softflag |= OB_SB_RESET;
|
||||
}
|
||||
|
||||
/* reset all motion */
|
||||
void sbObjectReset(Object *ob, float (*vertexCos)[3])
|
||||
static int object_has_edges(Object *ob)
|
||||
{
|
||||
SoftBody *sb= ob->soft;
|
||||
BodyPoint *bp;
|
||||
int a;
|
||||
|
||||
if(sb==NULL) return;
|
||||
if(sb->keys && sb->totkey) return; // only as cpu time saver
|
||||
|
||||
sb->ctime= bsystem_time(ob, NULL, (float)G.scene->r.cfra, 0.0);
|
||||
|
||||
object_update_softbody(ob, vertexCos);
|
||||
|
||||
for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) {
|
||||
// origS is previous timestep
|
||||
VECCOPY(bp->origS, bp->origE);
|
||||
VECCOPY(bp->pos, bp->origE);
|
||||
VECCOPY(bp->origT, bp->origE);
|
||||
bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f;
|
||||
|
||||
// no idea about the Heun stuff! (ton)
|
||||
VECCOPY(bp->prevpos, bp->pos);
|
||||
VECCOPY(bp->prevvec, bp->vec);
|
||||
VECCOPY(bp->prevdx, bp->vec);
|
||||
VECCOPY(bp->prevdv, bp->vec);
|
||||
if(ob->type==OB_MESH) {
|
||||
Mesh *me= ob->data;
|
||||
return (me->medge && me->totedge);
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* simulates one step. framenr is in frames */
|
||||
/* copies result back to object, displist */
|
||||
void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3])
|
||||
void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
SoftBody *sb;
|
||||
Base *base;
|
||||
BodyPoint *bp;
|
||||
float dtime;
|
||||
int timescale,t;
|
||||
int a,timescale,t;
|
||||
float ctime, forcetime;
|
||||
float err;
|
||||
|
||||
/* this variable is set while transform(). with lattices also having a softbody,
|
||||
it calls lattice_modifier() all the time... has no displist yet. Is temporal
|
||||
hack which should be resolved with proper depgraph usage + storage of deformed
|
||||
vertices in lattice (ton) */
|
||||
if(G.moving) return;
|
||||
|
||||
/* baking works with global time */
|
||||
if(!(ob->softflag & OB_SB_BAKEDO) )
|
||||
if(softbody_baked_step(ob, framenr, vertexCos) ) return;
|
||||
|
||||
/* remake softbody if: */
|
||||
if( (ob->softflag & OB_SB_REDO) || // signal after weightpainting
|
||||
(ob->soft==NULL) || // just to be nice we allow full init
|
||||
(ob->soft->bpoint==NULL) ) // after reading new file, or acceptable as signal to refresh
|
||||
sbObjectToSoftbody(ob, vertexCos);
|
||||
if(softbody_baked_step(ob, framenr, vertexCos, numVerts) ) return;
|
||||
|
||||
/* remake softbody if: */
|
||||
if( (ob->softflag & OB_SB_REDO) || // signal after weightpainting
|
||||
(ob->soft==NULL) || // just to be nice we allow full init
|
||||
(ob->soft->bpoint==NULL) || // after reading new file, or acceptable as signal to refresh
|
||||
(numVerts!=ob->soft->totpoint) || // should never happen, just to be safe
|
||||
((ob->softflag & OB_SB_EDGES) && !ob->soft->bspring && object_has_edges(ob))) // happens when in UI edges was set
|
||||
convert_object_to_sb(ob, numVerts);
|
||||
|
||||
sb= ob->soft;
|
||||
|
||||
/* still no points? go away */
|
||||
@@ -1377,23 +1206,53 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3])
|
||||
}
|
||||
|
||||
/* checking time: */
|
||||
|
||||
ctime= bsystem_time(ob, NULL, framenr, 0.0);
|
||||
dtime= ctime - sb->ctime;
|
||||
// bail out for negative or for large steps
|
||||
if(dtime<0.0 || dtime >= 9.9*G.scene->r.framelen) { // G.scene->r.framelen corrects for frame-mapping, so this is actually 10 frames for UI
|
||||
sbObjectReset(ob, vertexCos);
|
||||
return;
|
||||
|
||||
if (ob->softflag&OB_SB_RESET) {
|
||||
dtime = 0.0;
|
||||
} else {
|
||||
dtime= ctime - sb->ctime;
|
||||
}
|
||||
|
||||
|
||||
/* the simulator */
|
||||
|
||||
if(dtime > 0.0) { // note: what does this mean now? (ton)
|
||||
//answer (BM) :
|
||||
//dtime is still in [frames]
|
||||
//we made sure dtime is >= 0.0
|
||||
//but still need to handle dtime == 0.0 -> just return sb as is, just to be nice
|
||||
object_update_softbody(ob, vertexCos);
|
||||
|
||||
|
||||
/* update the vertex locations */
|
||||
if (dtime!=0.0) {
|
||||
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
|
||||
VECCOPY(bp->origS, bp->origE);
|
||||
VECCOPY(bp->origE, vertexCos[a]);
|
||||
Mat4MulVecfl(ob->obmat, bp->origE);
|
||||
VECCOPY(bp->origT, bp->origE);
|
||||
}
|
||||
}
|
||||
|
||||
// G.scene->r.framelen corrects for frame-mapping, so this is actually 10 frames for UI
|
||||
if((ob->softflag&OB_SB_RESET) || dtime<0.0 || dtime>=9.9*G.scene->r.framelen) {
|
||||
for(a=0,bp=sb->bpoint; a<numVerts; a++, bp++) {
|
||||
VECCOPY(bp->pos, vertexCos[a]);
|
||||
Mat4MulVecfl(ob->obmat, bp->pos); // yep, sofbody is global coords
|
||||
VECCOPY(bp->origS, bp->pos);
|
||||
VECCOPY(bp->origE, bp->pos);
|
||||
VECCOPY(bp->origT, bp->pos);
|
||||
bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f;
|
||||
|
||||
// no idea about the Heun stuff! (ton)
|
||||
VECCOPY(bp->prevpos, bp->pos);
|
||||
VECCOPY(bp->prevvec, bp->vec);
|
||||
VECCOPY(bp->prevdx, bp->vec);
|
||||
VECCOPY(bp->prevdv, bp->vec);
|
||||
}
|
||||
|
||||
for(a=0; a<sb->totspring; a++) {
|
||||
BodySpring *bs = &sb->bspring[a];
|
||||
|
||||
bs->len= VecLenf(sb->bpoint[bs->v1].origS, sb->bpoint[bs->v2].origS);
|
||||
}
|
||||
|
||||
ob->softflag &= ~OB_SB_RESET;
|
||||
}
|
||||
else if(dtime>0.0) {
|
||||
if (TRUE) { // RSOL1 always true now (ton)
|
||||
/* special case of 2nd order Runge-Kutta type AKA Heun */
|
||||
float timedone =0.0; // how far did we get without violating error condition
|
||||
@@ -1486,20 +1345,11 @@ void sbObjectStep(Object *ob, float framenr, float (*vertexCos)[3])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* and apply to vertices */
|
||||
softbody_to_object(ob, vertexCos);
|
||||
|
||||
sb->ctime= ctime;
|
||||
} // if(ABS(dtime) > 0.0)
|
||||
else {
|
||||
// rule : you have asked for the current state of the softobject
|
||||
// since dtime= ctime - ob->soft->ctime== 0.0;
|
||||
// and we were not notifified about any other time changes
|
||||
// so here it is !
|
||||
softbody_to_object(ob, vertexCos);
|
||||
}
|
||||
|
||||
softbody_to_object(ob, vertexCos, numVerts);
|
||||
sb->ctime= ctime;
|
||||
|
||||
/* reset deflector cache */
|
||||
for(base= G.scene->base.first; base; base= base->next) {
|
||||
if(base->object->sumohandle) {
|
||||
|
||||
@@ -119,6 +119,7 @@
|
||||
#include "BKE_effect.h" // for give_parteff
|
||||
#include "BKE_global.h" // for G
|
||||
#include "BKE_property.h" // for get_property
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_library.h" // for wich_libbase
|
||||
#include "BKE_main.h" // for Main
|
||||
#include "BKE_mesh.h" // for ME_ defines (patching)
|
||||
@@ -4863,7 +4864,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(main->versionfile <= 238) {
|
||||
Lattice *lt;
|
||||
|
||||
for (lt=main->latt.first; lt; lt=lt->id.next) {
|
||||
if (lt->fu==0.0 && lt->fv==0.0 && lt->fw==0.0) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
|
||||
|
||||
|
||||
@@ -422,6 +422,7 @@ enum {
|
||||
#define B_RESIZELAT 2601
|
||||
#define B_DRAWLAT 2602
|
||||
#define B_LATTCHANGED 2603
|
||||
#define B_REGULARLAT 2604
|
||||
|
||||
/* *********************** */
|
||||
#define B_GAMEBUTS 2800
|
||||
|
||||
@@ -42,14 +42,16 @@ typedef struct Lattice {
|
||||
ID id;
|
||||
|
||||
short pntsu, pntsv, pntsw, flag;
|
||||
short opntsu, opntsv, opntsw, pad2;
|
||||
char typeu, typev, typew, type;
|
||||
int pad;
|
||||
|
||||
float fu, fv, fw, du, dv, dw;
|
||||
|
||||
struct BPoint *def;
|
||||
|
||||
struct Ipo *ipo;
|
||||
struct Key *key;
|
||||
|
||||
} Lattice;
|
||||
|
||||
/* ***************** LATTICE ********************* */
|
||||
|
||||
@@ -118,6 +118,7 @@ typedef struct SoftBody {
|
||||
#define OB_SB_REDO 32
|
||||
#define OB_SB_BAKESET 64
|
||||
#define OB_SB_BAKEDO 128
|
||||
#define OB_SB_RESET 256
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -423,10 +423,7 @@ static PyObject *Lattice_setPartitions( BPy_Lattice * self, PyObject * args )
|
||||
return ( EXPP_ReturnPyObjError( PyExc_RuntimeError,
|
||||
"partition values must be 2 or greater" ) );
|
||||
|
||||
bl_Lattice->pntsu = ( short ) x;
|
||||
bl_Lattice->pntsv = ( short ) y;
|
||||
bl_Lattice->pntsw = ( short ) z;
|
||||
resizelattice( bl_Lattice );
|
||||
resizelattice(bl_Lattice, x, y, z, NULL);
|
||||
|
||||
Py_INCREF( Py_None );
|
||||
return Py_None;
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
@@ -511,6 +512,7 @@ void do_modifier_panels(unsigned short event)
|
||||
break;
|
||||
|
||||
case B_MODIFIER_RECALC:
|
||||
ob->softflag |= OB_SB_RESET;
|
||||
allqueue(REDRAWBUTSEDIT, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWOOPS, 0);
|
||||
@@ -700,8 +702,8 @@ static void modifiers_applyModifier(void *obv, void *mdv)
|
||||
if (G.obedit) {
|
||||
error("Modifiers cannot be applied in editmode");
|
||||
return;
|
||||
} else if (me->id.us>1) {
|
||||
error("Modifiers cannot be applied to a multi-user mesh");
|
||||
} else if (((ID*) ob->data)->us>1) {
|
||||
error("Modifiers cannot be applied to multi-user data");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -710,29 +712,54 @@ static void modifiers_applyModifier(void *obv, void *mdv)
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX, only for mesh
|
||||
if (ob->type==OB_MESH) {
|
||||
dm = mesh_create_derived_for_modifier(ob, md);
|
||||
if (!dm) {
|
||||
error("Modifier is disabled or returned error, skipping apply");
|
||||
return;
|
||||
}
|
||||
|
||||
dm = mesh_create_derived_for_modifier(ob, md);
|
||||
if (!dm) {
|
||||
error("Modifier is disabled or returned error, skipping apply");
|
||||
return;
|
||||
}
|
||||
dlm= dm->convertToDispListMesh(dm, 0);
|
||||
|
||||
dlm= dm->convertToDispListMesh(dm, 0);
|
||||
|
||||
if ((!me->tface || dlm->tface) || okee("Applying will delete mesh UVs and vertex colors")) {
|
||||
if ((!me->mcol || dlm->mcol) || okee("Applying will delete mesh vertex colors")) {
|
||||
if (dlm->totvert==me->totvert || okee("Applying will delete mesh sticky, keys, and vertex groups")) {
|
||||
displistmesh_to_mesh(dlm, me);
|
||||
converted = 1;
|
||||
if ((!me->tface || dlm->tface) || okee("Applying will delete mesh UVs and vertex colors")) {
|
||||
if ((!me->mcol || dlm->mcol) || okee("Applying will delete mesh vertex colors")) {
|
||||
if (dlm->totvert==me->totvert || okee("Applying will delete mesh sticky, keys, and vertex groups")) {
|
||||
displistmesh_to_mesh(dlm, me);
|
||||
converted = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!converted) {
|
||||
displistmesh_free(dlm);
|
||||
if (!converted) {
|
||||
displistmesh_free(dlm);
|
||||
}
|
||||
dm->release(dm);
|
||||
}
|
||||
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
Curve *cu = ob->data;
|
||||
int numVerts;
|
||||
float (*vertexCos)[3];
|
||||
|
||||
if (!okee("Apply will only change CV points, not tesselated/bevel vertices"))
|
||||
return;
|
||||
|
||||
if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md))) {
|
||||
error("Modifier is disabled, skipping apply");
|
||||
return;
|
||||
}
|
||||
|
||||
vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
|
||||
mti->deformVerts(md, ob, NULL, vertexCos, numVerts);
|
||||
curve_applyVertexCos(cu, &cu->nurb, vertexCos);
|
||||
MEM_freeN(vertexCos);
|
||||
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
}
|
||||
else {
|
||||
error("Cannot apply modifier for this object type");
|
||||
return;
|
||||
}
|
||||
dm->release(dm);
|
||||
|
||||
BLI_remlink(&ob->modifiers, md);
|
||||
modifier_free(md);
|
||||
@@ -1972,13 +1999,23 @@ void do_latticebuts(unsigned short event)
|
||||
if(ob->type!=OB_LATTICE) return;
|
||||
|
||||
switch(event) {
|
||||
case B_REGULARLAT:
|
||||
if(ob) {
|
||||
lt = ob->data;
|
||||
if(ob==G.obedit) resizelattice(editLatt, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
|
||||
else resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, NULL);
|
||||
ob->softflag |= OB_SB_REDO;
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
case B_RESIZELAT:
|
||||
if(ob) {
|
||||
if(ob==G.obedit) resizelattice(editLatt);
|
||||
else resizelattice(ob->data);
|
||||
lt = ob->data;
|
||||
resizelattice(ob->data, lt->opntsu, lt->opntsv, lt->opntsw, ob);
|
||||
ob->softflag |= OB_SB_REDO;
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
}
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
break;
|
||||
case B_DRAWLAT:
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
@@ -2009,24 +2046,28 @@ static void editing_panel_lattice_type(Object *ob, Lattice *lt)
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
uiDefButS(block, NUM, B_RESIZELAT, "U:", 469, 178,100,19, <->pntsu, 1.0, 64.0, 0, 0, "Points in U direction");
|
||||
lt->opntsu = lt->pntsu;
|
||||
lt->opntsv = lt->pntsv;
|
||||
lt->opntsw = lt->pntsw;
|
||||
|
||||
uiDefButS(block, NUM, B_RESIZELAT, "U:", 469, 178,100,19, <->opntsu, 1.0, 64.0, 0, 0, "Points in U direction");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 178, 40, 19, <->typeu, 1.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 178, 40, 19, <->typeu, 1.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 178, 40, 19, <->typeu, 1.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation");
|
||||
|
||||
uiDefButS(block, NUM, B_RESIZELAT, "V:", 469, 156,100,19, <->pntsv, 1.0, 64.0, 0, 0, "Points in V direction");
|
||||
uiDefButS(block, NUM, B_RESIZELAT, "V:", 469, 156,100,19, <->opntsv, 1.0, 64.0, 0, 0, "Points in V direction");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 156, 40, 19, <->typev, 2.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 156, 40, 19, <->typev, 2.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 156, 40, 19, <->typev, 2.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation");
|
||||
|
||||
uiDefButS(block, NUM, B_RESIZELAT, "W:", 469, 134,100,19, <->pntsw, 1.0, 64.0, 0, 0, "Points in W direction");
|
||||
uiDefButS(block, NUM, B_RESIZELAT, "W:", 469, 134,100,19, <->opntsw, 1.0, 64.0, 0, 0, "Points in W direction");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "Lin", 572, 134, 40, 19, <->typew, 3.0, (float)KEY_LINEAR, 0, 0, "Set Linear interpolation");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "Card", 613, 134, 40, 19, <->typew, 3.0, (float)KEY_CARDINAL, 0, 0, "Set Cardinal interpolation");
|
||||
uiDefButC(block, ROW, B_LATTCHANGED, "B", 652, 134, 40, 19, <->typew, 3.0, (float)KEY_BSPLINE, 0, 0, "Set B-spline interpolation");
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefBut(block, BUT, B_RESIZELAT, "Make Regular", 469,98,102,31, 0, 0, 0, 0, 0, "Make Lattice regular");
|
||||
uiDefBut(block, BUT, B_REGULARLAT, "Make Regular", 469,98,102,31, 0, 0, 0, 0, 0, "Make Lattice regular");
|
||||
|
||||
uiClearButLock();
|
||||
uiDefButBitS(block, TOG, LT_OUTSIDE, B_LATTCHANGED, "Outside", 571,98,122,31, <->flag, 0, 0, 0, 0, "Only draw, and take into account, the outer vertices");
|
||||
@@ -3229,6 +3270,7 @@ void editing_panels()
|
||||
lt= ob->data;
|
||||
editing_panel_links(ob); // no editmode!
|
||||
editing_panel_lattice_type(ob, lt);
|
||||
editing_panel_modifiers(ob);
|
||||
break;
|
||||
|
||||
case OB_LAMP:
|
||||
|
||||
@@ -1044,7 +1044,7 @@ static void softbody_bake(Object *ob)
|
||||
G.scene->r.framelen= 1.0; // baking has to be in uncorrected time
|
||||
CFRA= sb->sfra;
|
||||
update_for_newframe_muted(); // put everything on this frame
|
||||
sbObjectToSoftbody(ob, NULL); // put softbody in restposition
|
||||
sbObjectToSoftbody(ob); // put softbody in restposition
|
||||
ob->softflag |= OB_SB_BAKEDO;
|
||||
|
||||
curarea->win_swap= 0; // clean swapbuffers
|
||||
@@ -1069,7 +1069,7 @@ static void softbody_bake(Object *ob)
|
||||
if(event==ESCKEY) break;
|
||||
}
|
||||
|
||||
if(event==ESCKEY) sbObjectToSoftbody(ob, NULL); // clears all
|
||||
if(event==ESCKEY) sbObjectToSoftbody(ob); // clears all
|
||||
|
||||
/* restore */
|
||||
waitcursor(0);
|
||||
@@ -1157,7 +1157,7 @@ void do_object_panels(unsigned short event)
|
||||
break;
|
||||
case B_SOFTBODY_BAKE_FREE:
|
||||
ob= OBACT;
|
||||
if(ob && ob->soft) sbObjectToSoftbody(ob, NULL);
|
||||
if(ob && ob->soft) sbObjectToSoftbody(ob);
|
||||
allqueue(REDRAWBUTSOBJECT, 0);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
break;
|
||||
|
||||
@@ -786,51 +786,32 @@ void drawcamera(Object *ob)
|
||||
}
|
||||
}
|
||||
|
||||
static void tekenvertslatt(short sel)
|
||||
static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel)
|
||||
{
|
||||
Lattice *lt;
|
||||
BPoint *bp;
|
||||
float size;
|
||||
int a, u, v, w;
|
||||
|
||||
size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
|
||||
glPointSize(size);
|
||||
|
||||
if(sel) BIF_ThemeColor(TH_VERTEX_SELECT);
|
||||
else BIF_ThemeColor(TH_VERTEX);
|
||||
BPoint *bp = lt->def;
|
||||
float *co = dl?dl->verts:NULL;
|
||||
int u, v, w;
|
||||
|
||||
BIF_ThemeColor(sel?TH_VERTEX_SELECT:TH_VERTEX);
|
||||
glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
|
||||
bglBegin(GL_POINTS);
|
||||
|
||||
bp= editLatt->def;
|
||||
lt= editLatt;
|
||||
|
||||
if(lt->flag & LT_OUTSIDE) {
|
||||
|
||||
for(w=0; w<lt->pntsw; w++) {
|
||||
int wxt = (w==0 || w==lt->pntsw-1);
|
||||
for(v=0; v<lt->pntsv; v++) {
|
||||
int vxt = (v==0 || v==lt->pntsv-1);
|
||||
for(u=0; u<lt->pntsu; u++, bp++) {
|
||||
int uxt = (u==0 || u==lt->pntsu-1);
|
||||
if(uxt || vxt || wxt) {
|
||||
if(bp->hide==0) {
|
||||
if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec);
|
||||
for(w=0; w<lt->pntsw; w++) {
|
||||
int wxt = (w==0 || w==lt->pntsw-1);
|
||||
for(v=0; v<lt->pntsv; v++) {
|
||||
int vxt = (v==0 || v==lt->pntsv-1);
|
||||
for(u=0; u<lt->pntsu; u++, bp++, co+=3) {
|
||||
int uxt = (u==0 || u==lt->pntsu-1);
|
||||
if(!(lt->flag & LT_OUTSIDE) || uxt || vxt || wxt) {
|
||||
if(bp->hide==0) {
|
||||
if((bp->f1 & 1)==sel) {
|
||||
bglVertex3fv(dl?co:bp->vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
|
||||
while(a--) {
|
||||
if(bp->hide==0) {
|
||||
if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec);
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
|
||||
glPointSize(1.0);
|
||||
bglEnd();
|
||||
@@ -839,119 +820,74 @@ static void tekenvertslatt(short sel)
|
||||
void lattice_foreachScreenVert(void (*func)(void *userData, BPoint *bp, int x, int y), void *userData)
|
||||
{
|
||||
int i, N = editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
|
||||
DispList *dl = find_displist(&G.obedit->disp, DL_VERTS);
|
||||
float *co = dl?dl->verts:NULL;
|
||||
BPoint *bp = editLatt->def;
|
||||
float mat[4][4];
|
||||
short s[2];
|
||||
|
||||
view3d_get_object_project_mat(curarea, G.obedit, mat);
|
||||
|
||||
for (i=0; i<N; i++) {
|
||||
BPoint *bp = &editLatt->def[i];
|
||||
|
||||
for (i=0; i<N; i++, bp++, co+=3) {
|
||||
if (bp->hide==0) {
|
||||
view3d_project_short(curarea, bp->vec, s, mat);
|
||||
view3d_project_short(curarea, dl?co:bp->vec, s, mat);
|
||||
func(userData, bp, s[0], s[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w)
|
||||
{
|
||||
int index = ((w*lt->pntsv + v)*lt->pntsu) + u;
|
||||
|
||||
if (dl) {
|
||||
glVertex3fv(&dl->verts[index*3]);
|
||||
} else {
|
||||
glVertex3fv(lt->def[index].vec);
|
||||
}
|
||||
}
|
||||
static void drawlattice(Object *ob)
|
||||
{
|
||||
Lattice *lt;
|
||||
BPoint *bp, *bpu;
|
||||
int u, v, w, dv, dw, uxt, vxt, wxt;
|
||||
DispList *dl;
|
||||
int u, v, w;
|
||||
|
||||
lt= ob->data;
|
||||
lt= (ob==G.obedit)?editLatt:ob->data;
|
||||
dl= find_displist(&ob->disp, DL_VERTS);
|
||||
if(ob==G.obedit) {
|
||||
bp= editLatt->def;
|
||||
|
||||
cpack(0x004000);
|
||||
}
|
||||
else {
|
||||
do_latt_key(lt);
|
||||
bp= lt->def;
|
||||
}
|
||||
|
||||
dv= lt->pntsu;
|
||||
dw= dv*lt->pntsv;
|
||||
|
||||
if(lt->flag & LT_OUTSIDE) {
|
||||
|
||||
for(w=0; w<lt->pntsw; w++) {
|
||||
|
||||
if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
|
||||
|
||||
for(v=0; v<lt->pntsv; v++) {
|
||||
|
||||
if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
|
||||
|
||||
for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
|
||||
|
||||
if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
|
||||
|
||||
if(uxt || vxt || wxt) {
|
||||
|
||||
if(w && (uxt || vxt)) {
|
||||
glBegin(GL_LINES);
|
||||
for(w=0; w<lt->pntsw; w++) {
|
||||
int wxt = (w==0 || w==lt->pntsw-1);
|
||||
for(v=0; v<lt->pntsv; v++) {
|
||||
int vxt = (v==0 || v==lt->pntsv-1);
|
||||
for(u=0; u<lt->pntsu; u++) {
|
||||
int uxt = (u==0 || u==lt->pntsu-1);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
|
||||
glEnd();
|
||||
}
|
||||
if(v && (uxt || wxt)) {
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
|
||||
glEnd();
|
||||
}
|
||||
if(u && (vxt || wxt)) {
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
bpu= bp;
|
||||
if(w && ((uxt || vxt) || !(lt->flag & LT_OUTSIDE))) {
|
||||
drawlattice__point(lt, dl, u, v, w-1);
|
||||
drawlattice__point(lt, dl, u, v, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(w=0; w<lt->pntsw; w++) {
|
||||
|
||||
for(v=0; v<lt->pntsv; v++) {
|
||||
|
||||
for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
|
||||
|
||||
if(w) {
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
|
||||
glEnd();
|
||||
}
|
||||
if(v) {
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
|
||||
glEnd();
|
||||
}
|
||||
if(u) {
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
|
||||
glEnd();
|
||||
}
|
||||
bpu= bp;
|
||||
if(v && ((uxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
|
||||
drawlattice__point(lt, dl, u, v-1, w);
|
||||
drawlattice__point(lt, dl, u, v, w);
|
||||
}
|
||||
if(u && ((vxt || wxt) || !(lt->flag & LT_OUTSIDE))) {
|
||||
drawlattice__point(lt, dl, u-1, v, w);
|
||||
drawlattice__point(lt, dl, u, v, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
if(ob==G.obedit) {
|
||||
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
|
||||
|
||||
tekenvertslatt(0);
|
||||
tekenvertslatt(1);
|
||||
lattice_draw_verts(lt, dl, 0);
|
||||
lattice_draw_verts(lt, dl, 1);
|
||||
|
||||
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
@@ -607,7 +607,7 @@ static CutCurve *get_mouse_trail(int *len, char mode)
|
||||
*/
|
||||
|
||||
/* prototype */
|
||||
short seg_intersect(struct EditEdge * e, CutCurve *c, int len);
|
||||
static short seg_intersect(struct EditEdge * e, CutCurve *c, int len);
|
||||
|
||||
void KnifeSubdivide(char mode)
|
||||
{
|
||||
|
||||
@@ -1311,7 +1311,7 @@ void make_parent(void)
|
||||
}
|
||||
else {
|
||||
|
||||
base->object->recalc |= OB_RECALC_OB;
|
||||
base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
|
||||
|
||||
/* the ifs below are horrible code (ton) */
|
||||
|
||||
@@ -1363,7 +1363,6 @@ void make_parent(void)
|
||||
|
||||
if(par->type==OB_ARMATURE && mode == PARSKEL){
|
||||
verify_defgroups(base->object);
|
||||
base->object->recalc |= OB_RECALC_DATA;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1523,9 +1522,9 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un
|
||||
|
||||
if(sb->keys) {
|
||||
if( okee("Erase Baked SoftBody") )
|
||||
sbObjectToSoftbody(ob, NULL);
|
||||
sbObjectToSoftbody(ob);
|
||||
}
|
||||
else sbObjectToSoftbody(ob, NULL);
|
||||
else sbObjectToSoftbody(ob);
|
||||
}
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
|
||||
|
||||
|
||||
@@ -1417,7 +1417,7 @@ void special_aftertrans_update(short cancelled)
|
||||
|
||||
ob= base->object;
|
||||
|
||||
if(modifiers_isSoftbodyEnabled(ob)) sbObjectReset(ob, NULL);
|
||||
if(modifiers_isSoftbodyEnabled(ob)) ob->softflag |= OB_SB_RESET;
|
||||
|
||||
/* Set autokey if necessary */
|
||||
if ((G.flags & G_RECORDKEYS) && (!cancelled) && (base->flag & SELECT)){
|
||||
|
||||
Reference in New Issue
Block a user