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:
-rw-r--r--source/blender/blenkernel/BKE_deform.h11
-rw-r--r--source/blender/blenkernel/BKE_object.h1
-rw-r--r--source/blender/blenkernel/intern/anim.c10
-rw-r--r--source/blender/blenkernel/intern/armature.c6
-rw-r--r--source/blender/blenkernel/intern/deform.c255
-rw-r--r--source/blender/blenkernel/intern/displist.c107
-rw-r--r--source/blender/blenkernel/intern/lattice.c288
-rw-r--r--source/blender/blenkernel/intern/object.c24
-rw-r--r--source/blender/blenloader/intern/readfile.c22
-rw-r--r--source/blender/blenloader/intern/writefile.c8
-rw-r--r--source/blender/include/BDR_editcurve.h2
-rw-r--r--source/blender/include/BDR_editobject.h1
-rw-r--r--source/blender/include/butspace.h5
-rw-r--r--source/blender/makesdna/DNA_curve_types.h1
-rw-r--r--source/blender/makesdna/DNA_object_types.h22
-rw-r--r--source/blender/renderconverter/intern/convertBlenderScene.c68
-rw-r--r--source/blender/src/buttons_editing.c15
-rw-r--r--source/blender/src/buttons_object.c107
-rw-r--r--source/blender/src/drawobject.c70
-rw-r--r--source/blender/src/editcurve.c63
-rw-r--r--source/blender/src/editobject.c499
-rw-r--r--source/blender/src/space.c35
22 files changed, 1315 insertions, 305 deletions
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index e7494f28fc4..411225b0635 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -1,8 +1,8 @@
/* BKE_deform.h June 2001
*
- * support for deformation groups
+ * support for deformation groups and hooks
*
- * Reevan McKay
+ * Reevan McKay et al
*
* $Id$
*
@@ -46,5 +46,12 @@ void copy_defgroups (struct ListBase *lb1, struct ListBase *lb2);
struct bDeformGroup* copy_defgroup (struct bDeformGroup *ingroup);
void color_temperature (float input, unsigned char *r, unsigned char *g, unsigned char *b);
+void hook_object_deform(struct Object *ob, int index, float *vec);
+
+int curve_modifier(struct Object *ob, char mode);
+int mesh_modifier(struct Object *ob, char mode);
+int lattice_modifier(struct Object *ob, char mode);
+
+
#endif
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 3bd2ff432b9..a5384ee2ae2 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -93,7 +93,6 @@ void minmax_object(struct Object *ob, float *min, float *max);
void solve_tracking (struct Object *ob, float targetmat[][4]);
void solve_constraints (struct Object *ob, short obtype, void *obdata, float ctime);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index fc7953c051d..1cd442a5391 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -97,8 +97,6 @@ void calc_curvepath(Object *ob)
if(cu->path) free_path(cu->path);
cu->path= 0;
- if((cu->flag & CU_PATH)==0) return;
-
bl= cu->bev.first;
if(bl==0) {
makeDispList(ob);
@@ -213,10 +211,13 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
float *fp, *p0, *p1, *p2, *p3, fac;
float data[4];
int cycl=0, s0, s1, s2, s3;
-
+
if(ob==0 || ob->type != OB_CURVE) return 0;
cu= ob->data;
- if(cu->path==0 || cu->path->data==0) calc_curvepath(ob);
+ if(cu->path==0 || cu->path->data==0) {
+ calc_curvepath(ob);
+ if(cu->path==0 || cu->path->data==0) return 0;
+ }
path= cu->path;
fp= path->data;
@@ -224,7 +225,6 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
bl= cu->bev.first;
if(bl && bl->poly> -1) cycl= 1;
- /* ctime is between 0.0-1.0 */
ctime *= (path->len-1);
s1= (int)floor(ctime);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index ae73d7f5059..0c30e53ec16 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1197,9 +1197,13 @@ void make_displists_by_armature (Object *ob)
for (base= G.scene->base.first; base; base= base->next){
if ((ob==base->object->parent) && (base->lay & G.scene->lay))
if ((base->object->partype==PARSKEL) || (base->object->type==OB_MBALL))
- makeDispList(base->object);
+ freedisplist(&base->object->disp);
}
}
+/*
+(ton) changed this; now a free displist is sufficient, drawobject.c will make disp
+*/
+
}
void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[][4], int root, int posed)
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index f1ba0324fc8..f3eab76a465 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -36,10 +36,23 @@
*/
#include <string.h>
+
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_lattice_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+
+#include "BKE_curve.h"
#include "BKE_deform.h"
+#include "BKE_displist.h"
+#include "BKE_lattice.h"
+#include "BKE_utildefines.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -117,3 +130,243 @@ bDeformGroup* copy_defgroup (bDeformGroup *ingroup)
return outgroup;
}
+/* *************** HOOK ****************** */
+
+/* vec==NULL: init
+ vec is supposed to be local coord
+*/
+
+void hook_object_deform(Object *ob, int index, float *vec)
+{
+ float totforce;
+ ObHook *hook;
+ float vect[3], vectot[3];
+
+ if(ob->hooks.first==NULL) return;
+
+ /* reinitialize if... */
+ if(vec==NULL) {
+ totforce= 0.0;
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ if(hook->parent) {
+ hook->curindex= 0;
+ Mat4Invert(ob->imat, ob->obmat);
+ /* apparently this call goes from right to left... */
+ Mat4MulSerie(hook->mat, ob->imat, hook->parent->obmat, hook->parentinv, NULL,
+ NULL, NULL, NULL, NULL);
+ }
+ }
+ return;
+ }
+
+ totforce= 0.0;
+ vectot[0]= vectot[1]= vectot[2]= 0.0;
+
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ if(hook->parent) {
+
+ /* is 'index' in hook array? */
+ while(hook->curindex < hook->totindex-1) {
+ if( hook->indexar[hook->curindex] < index ) hook->curindex++;
+ else break;
+ }
+
+ if( hook->indexar[hook->curindex]==index ) {
+ float fac= hook->force;
+
+ totforce+= fac;
+
+ VecMat4MulVecfl(vect, hook->mat, vec);
+ vectot[0]+= fac*vect[0];
+ vectot[1]+= fac*vect[1];
+ vectot[2]+= fac*vect[2];
+ }
+ }
+ }
+
+ /* if totforce < 1.0, we take old position also into account */
+ if(totforce<1.0) {
+ vectot[0]+= (1.0-totforce)*vec[0];
+ vectot[1]+= (1.0-totforce)*vec[1];
+ vectot[2]+= (1.0-totforce)*vec[2];
+ }
+ else VecMulf(vectot, 1.0/totforce);
+
+ VECCOPY(vec, vectot);
+}
+
+
+/* modifiers: hooks, deform, softbody
+ mode=='s' is start, 'e' end
+*/
+
+int mesh_modifier(Object *ob, char mode)
+{
+ static MVert *mvert=NULL;
+ Mesh *me= ob->data;
+ MVert *mv;
+ int a, done=0;
+
+ /* conditions if it's needed */
+ if(ob->hooks.first);
+ else if(ob->parent && ob->parent->type==OB_LATTICE);
+ else if(ob->parent && ob->partype==PARSKEL);
+ else return 0;
+
+ if(me->totvert==0) return 0;
+
+ if(mode=='s') { // "start"
+ /* copy */
+ mvert= MEM_dupallocN(me->mvert);
+
+ /* hooks */
+ if(ob->hooks.first) {
+ done= 1;
+
+ /* NULL signals initialize */
+ hook_object_deform(ob, 0, NULL);
+
+ for(a=0, mv= me->mvert; a<me->totvert; a++, mv++) {
+ hook_object_deform(ob, a, mv->co);
+ }
+ }
+
+ /* deform: input mesh, output ob dl_verts. is used by subsurf */
+ done |= object_deform(ob);
+
+ /* put deformed vertices in dl->verts, optional subsurf will replace that */
+ if(done) {
+ DispList *dl= find_displist_create(&ob->disp, DL_VERTS);
+ float *fp;
+
+ if(dl->verts) MEM_freeN(dl->verts);
+ dl->nr= me->totvert;
+ if(dl->nr) {
+
+ /* make disp array */
+ dl->verts= fp= MEM_mallocN(3*sizeof(float)*me->totvert, "deform1");
+ mv= me->mvert;
+ for(a=0; a<me->totvert; a++, mv++, fp+=3) {
+ VECCOPY(fp, mv->co);
+ }
+ }
+ }
+ }
+ else { // end
+ if(mvert) {
+ MEM_freeN(me->mvert);
+ me->mvert= mvert;
+ mvert= NULL;
+ }
+ }
+
+ return done;
+}
+
+int curve_modifier(Object *ob, char mode)
+{
+ static ListBase nurb={NULL, NULL};
+ Curve *cu= ob->data;
+ Nurb *nu, *newnu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a, index, done= 0;
+
+ /* conditions if it's needed */
+ if(ob->hooks.first);
+ else if(ob->parent && ob->partype==PARSKEL);
+ else if(ob->parent && ob->parent->type==OB_LATTICE);
+ else return 0;
+
+ if(mode=='s') { // "start"
+ /* copy */
+ nurb.first= nurb.last= NULL;
+ nu= cu->nurb.first;
+ while(nu) {
+ newnu= duplicateNurb(nu);
+ BLI_addtail(&nurb, newnu);
+ nu= nu->next;
+ }
+
+ /* hooks */
+ if(ob->hooks.first) {
+ done= 1;
+
+ /* NULL signals initialize */
+ hook_object_deform(ob, 0, NULL);
+ index= 0;
+
+ nu= cu->nurb.first;
+ while(nu) {
+ if((nu->type & 7)==CU_BEZIER) {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--) {
+ hook_object_deform(ob, index++, bezt->vec[0]);
+ hook_object_deform(ob, index++, bezt->vec[1]);
+ hook_object_deform(ob, index++, bezt->vec[2]);
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+ while(a--) {
+ hook_object_deform(ob, index++, bp->vec);
+ bp++;
+ }
+ }
+
+ nu= nu->next;
+ }
+ }
+ }
+ else {
+ /* paste */
+ freeNurblist(&cu->nurb);
+ cu->nurb= nurb;
+ }
+
+ return done;
+}
+
+int lattice_modifier(Object *ob, char mode)
+{
+ static BPoint *bpoint;
+ Lattice *lt= ob->data;
+ BPoint *bp;
+ int a, index, done= 0;
+
+ /* conditions if it's needed */
+ if(ob->hooks.first);
+ else if(ob->parent && ob->partype==PARSKEL);
+ else return 0;
+
+ if(mode=='s') { // "start"
+ /* copy */
+ bpoint= MEM_dupallocN(lt->def);
+
+ /* hooks */
+ if(ob->hooks.first) {
+ done= 1;
+
+ /* NULL signals initialize */
+ hook_object_deform(ob, 0, NULL);
+ index= 0;
+ bp= lt->def;
+ a= lt->pntsu*lt->pntsv*lt->pntsw;
+ while(a--) {
+ hook_object_deform(ob, index++, bp->vec);
+ bp++;
+ }
+ }
+ }
+ else { // end
+ MEM_freeN(lt->def);
+ lt->def= bpoint;
+ bpoint= NULL;
+ }
+
+ return done;
+}
+
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 821a1a5bd7c..932eccb2357 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -70,6 +70,7 @@
#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_displist.h"
+#include "BKE_deform.h"
#include "BKE_object.h"
#include "BKE_world.h"
#include "BKE_mesh.h"
@@ -331,6 +332,20 @@ void freedisplist(ListBase *lb)
}
}
+static void freedisplist_object(Object *ob)
+{
+ freedisplist(&ob->disp);
+
+ if(ob->type==OB_MESH) {
+ Mesh *me= ob->data;
+ freedisplist(&me->disp);
+ }
+ else if(ob->type==OB_CURVE || ob->type==OB_SURF || ob->type==OB_FONT) {
+ Curve *cu= ob->data;
+ freedisplist(&cu->disp);
+ }
+}
+
void free_displist_by_type(ListBase *lb, int type)
{
DispList *dl;
@@ -1740,8 +1755,9 @@ void makeDispList(Object *ob)
tex_space_mesh(ob->data);
- /* deform: input mesh, output ob dl_verts. is used by subsurf */
- object_deform(ob);
+ if(ob!=G.obedit) {
+ mesh_modifier(ob, 's');
+ }
if(ob->effect.first) object_wave(ob);
@@ -1752,7 +1768,7 @@ void makeDispList(Object *ob)
dlm= subsurf_make_dispListMesh_from_editmesh(em, me->subdiv, me->flag, me->subsurftype);
} else {
DispList *dlVerts= find_displist(&ob->disp, DL_VERTS);
-
+ // not needed anymore, recode it (ton)
dlm= subsurf_make_dispListMesh_from_mesh(me, dlVerts?dlVerts->verts:NULL,
me->subdiv, me->flag);
}
@@ -1764,6 +1780,8 @@ void makeDispList(Object *ob)
free_displist_by_type(&me->disp, DL_MESH);
BLI_addtail(&me->disp, dl);
}
+
+ if(ob!=G.obedit) mesh_modifier(ob, 'e');
}
else if(ob->type==OB_MBALL) {
@@ -1783,8 +1801,11 @@ void makeDispList(Object *ob)
freedisplist(dispbase);
if(ob==G.obedit) nu= editNurb.first;
- else nu= cu->nurb.first;
-
+ else {
+ curve_modifier(ob, 's');
+ nu= cu->nurb.first;
+ }
+
while(nu) {
if(nu->hide==0) {
if(nu->pntsv==1) {
@@ -1856,7 +1877,8 @@ void makeDispList(Object *ob)
}
tex_space_curve(cu);
-
+
+ if(ob!=G.obedit) curve_modifier(ob, 'e');
if(ob!=G.obedit) object_deform(ob);
}
else if ELEM(ob->type, OB_CURVE, OB_FONT) {
@@ -1872,6 +1894,8 @@ void makeDispList(Object *ob)
BLI_freelistN(&(cu->bev));
+ if(ob!=G.obedit) curve_modifier(ob, 's');
+
if(ob==G.obedit) {
if(ob->type==OB_CURVE) curve_to_displist(&editNurb, dispbase);
else curve_to_displist(&cu->nurb, dispbase);
@@ -1986,12 +2010,14 @@ void makeDispList(Object *ob)
}
}
+ if(ob!=G.obedit) curve_modifier(ob, 'e');
if(ob!=G.obedit) object_deform(ob);
tex_space_curve(cu);
}
+ boundbox_displist(ob);
}
@@ -2294,12 +2320,13 @@ void imagestodisplist(void)
}
/* on frame change */
-
+/* new method: only frees displists, and relies on
+ drawobject.c & convertscene.c to build it when needed
+*/
void test_all_displists(void)
{
Base *base;
Object *ob;
- int done; /* prevent displist to be made too often */
unsigned int lay;
/* background */
@@ -2310,8 +2337,6 @@ void test_all_displists(void)
if(base->lay & lay) {
ob= base->object;
- done= 0;
-
if(ob->type==OB_MBALL && (ob->ipo || ob->parent)) {
// find metaball object holding the displist
// WARNING: if more metaballs have IPO's the displist
@@ -2321,44 +2346,62 @@ void test_all_displists(void)
if(ob->disp.first == NULL) {
ob= find_basis_mball(ob);
}
- // makeDispList(ob);
freedisplist(&ob->disp);
}
else if(ob->parent) {
- done= 1;
if (ob->parent->type == OB_LATTICE)
- makeDispList(ob);
+ freedisplist_object(ob);
else if ((ob->parent->type == OB_IKA) && (ob->partype == PARSKEL))
- makeDispList(ob);
+ freedisplist_object(ob);
else if ((ob->parent->type==OB_ARMATURE) && (ob->partype == PARSKEL))
- makeDispList(ob);
- else done= 0;
+ freedisplist_object(ob);
+ else if ((ob->parent->type==OB_CURVE) && (ob->partype == PARSKEL))
+ freedisplist_object(ob);
}
- /* warn, ob pointer changed in case of OB_MALL */
- if(done==0) {
- if ELEM(ob->type, OB_CURVE, OB_SURF) {
- if(ob!=G.obedit) {
- if( ((Curve *)(ob->data))->key ) makeDispList(ob);
- }
+ if(ob->hooks.first) {
+ ObHook *hook;
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ if(hook->parent) freedisplist_object(ob);
+ break;
}
- else if(ob->type==OB_FONT) {
+ }
+
+ /* warn, ob pointer changed in case of OB_MALL */
+
+ if ELEM(ob->type, OB_CURVE, OB_SURF) {
+ if(ob!=G.obedit) {
Curve *cu= ob->data;
- if(cu->textoncurve) {
- if( ((Curve *)cu->textoncurve->data)->key ) {
- text_to_curve(ob, 0);
- makeDispList(ob);
- }
+
+ if(cu->key ) freedisplist_object(ob); //makeDispList(ob);
+ if(cu->bevobj) {
+ Curve *cu1= cu->bevobj->data;
+ if(cu1->key ) freedisplist_object(ob);
+ }
+ if(cu->taperobj) {
+ Curve *cu1= cu->taperobj->data;
+ if(cu1->key ) freedisplist_object(ob);
}
}
- else if(ob->type==OB_MESH) {
- if(ob->effect.first) object_wave(ob);
- if(ob!=G.obedit) {
- if(( ((Mesh *)(ob->data))->key )||(ob->effect.first)) makeDispList(ob);
+ }
+ else if(ob->type==OB_FONT) {
+ Curve *cu= ob->data;
+ if(cu->textoncurve) {
+ if( ((Curve *)cu->textoncurve->data)->key ) {
+ text_to_curve(ob, 0);
+ freedisplist_object(ob); //makeDispList(ob);
}
}
}
+ else if(ob->type==OB_MESH) {
+ if(ob->effect.first) object_wave(ob);
+ if(ob!=G.obedit) {
+ if(( ((Mesh *)(ob->data))->key )||(ob->effect.first))
+ freedisplist_object(ob); //makeDispList(ob);
+ }
+ }
+
}
if(base->next==0 && G.scene->set && base==G.scene->base.last) base= G.scene->set->base.first;
else base= base->next;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 3cb2f20925f..959cb7001fb 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -53,23 +53,27 @@
#include "DNA_key_types.h"
#include "DNA_ika_types.h"
-#include "BKE_utildefines.h"
+#include "BKE_anim.h"
#include "BKE_armature.h"
-#include "BKE_library.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_screen.h"
+#include "BKE_curve.h"
+#include "BKE_deform.h"
#include "BKE_displist.h"
-#include "BKE_lattice.h"
+#include "BKE_global.h"
+#include "BKE_ika.h"
#include "BKE_key.h"
+#include "BKE_lattice.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
#include "BKE_object.h"
-#include "BKE_ika.h"
-#include "BKE_curve.h"
+#include "BKE_screen.h"
+#include "BKE_utildefines.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#include "blendef.h"
+
Lattice *editLatt=0, *deformLatt=0;
float *latticedata=0, latmat[4][4];
@@ -236,6 +240,7 @@ void init_latt_deform(Object *oblatt, Object *ob)
fp= latticedata= MEM_mallocN(sizeof(float)*3*deformLatt->pntsu*deformLatt->pntsv*deformLatt->pntsw, "latticedata");
+ lattice_modifier(oblatt, 's');
bp= deformLatt->def;
if(ob) where_is_object(ob);
@@ -279,6 +284,9 @@ void init_latt_deform(Object *oblatt, Object *ob)
}
vec[2]+= dw;
}
+
+ lattice_modifier(oblatt, 'e');
+
}
void calc_latt_deform(float *co)
@@ -383,6 +391,119 @@ void end_latt_deform()
latticedata= 0;
}
+ /* calculations is in local space of deformed object
+ so we store in latmat transform from path coord inside object
+ */
+typedef struct {
+ float dmin[3], dmax[3], dsize, dloc[3];
+ float curvespace[4][4], objectspace[4][4];
+} CurveDeform;
+
+static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd)
+{
+ Mat4Invert(ob->imat, ob->obmat);
+ Mat4MulMat4(cd->objectspace, par->obmat, ob->imat);
+ Mat4Invert(cd->curvespace, cd->objectspace);
+
+ // offset vector for 'no smear'
+ Mat4Invert(par->imat, par->obmat);
+ VecMat4MulVecfl(cd->dloc, par->imat, ob->obmat[3]);
+
+}
+
+/* this makes sure we can extend for non-cyclic */
+static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir) /* returns OK */
+{
+ Curve *cu= ob->data;
+ BevList *bl;
+ float ctime1;
+ int cycl=0;
+
+ /* test for cyclic */
+ bl= cu->bev.first;
+ if(bl && bl->poly> -1) cycl= 1;
+
+ if(cycl==0) {
+ ctime1= CLAMPIS(ctime, 0.0, 1.0);
+ }
+ else ctime1= ctime;
+
+ if(where_on_path(ob, ctime1, vec, dir)) {
+
+ if(cycl==0) {
+ Path *path= cu->path;
+ float dvec[3];
+
+ if(ctime < 0.0) {
+ VecSubf(dvec, path->data+4, path->data);
+ VecMulf(dvec, ctime*(float)path->len);
+ VECADD(vec, vec, dvec);
+ }
+ else if(ctime > 1.0) {
+ VecSubf(dvec, path->data+4*path->len-4, path->data+4*path->len-8);
+ VecMulf(dvec, (ctime-1.0)*(float)path->len);
+ VECADD(vec, vec, dvec);
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+ /* for each point, rotate & translate to curve */
+ /* use path, since it has constant distances */
+ /* co: local coord, result local too */
+static void calc_curve_deform(Object *par, float *co, short axis, CurveDeform *cd)
+{
+ Curve *cu= par->data;
+ float fac, loc[3], dir[3], *quat, mat[3][3], cent[3];
+ short upflag, index;
+
+ if(axis==OB_POSX || axis==OB_NEGX) {
+ upflag= OB_POSZ;
+ cent[0]= 0.0;
+ cent[1]= co[1];
+ cent[2]= co[2];
+ index= 0;
+ }
+ else if(axis==OB_POSY || axis==OB_NEGY) {
+ upflag= OB_POSZ;
+ cent[0]= co[0];
+ cent[1]= 0.0;
+ cent[2]= co[2];
+ index= 1;
+ }
+ else {
+ upflag= OB_POSY;
+ cent[0]= co[0];
+ cent[1]= co[1];
+ cent[2]= 0.0;
+ index= 2;
+ }
+ /* to be sure */
+ if(cu->path==NULL) calc_curvepath(par);
+
+ /* options */
+ if(cu->flag & CU_STRETCH)
+ fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
+ else
+ fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
+
+ if( where_on_path_deform(par, fac, loc, dir)) { /* returns OK */
+
+ quat= vectoquat(dir, axis, upflag);
+ QuatToMat3(quat, mat);
+
+ /* local rotation */
+ Mat3MulVecfl(mat, cent);
+
+ /* translation */
+ VECADD(co, cent, loc);
+
+ }
+
+}
+
static int _object_deform(Object *ob, int applyflag)
{
@@ -391,32 +512,59 @@ static int _object_deform(Object *ob, int applyflag)
DispList *dl;
MVert *mvert;
float *fp;
- int a, tot;
+ int a, tot, flag;
- if(ob->parent==0) return 0;
+ if(ob->parent==NULL) return 0;
/* always try to do the entire deform in this function: apply! */
-
- if(ob->parent->type==OB_LATTICE) {
+
+ if(ob->parent->type==OB_CURVE) {
+ CurveDeform cd;
- init_latt_deform(ob->parent, ob);
+ if (ob->partype != PARSKEL){
+ return 0;
+ }
+ cu= ob->parent->data;
+ flag= cu->flag;
+ cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
if(ob->type==OB_MESH) {
+
me= ob->data;
+ if(me->totvert==0) return 0;
- dl= find_displist_create(&ob->disp, DL_VERTS);
+ /* init deform */
+ init_curve_deform(ob->parent, ob, &cd);
- 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");
+ /* transformation to curve space, and min max*/
+ INIT_MINMAX(cd.dmin, cd.dmax);
+
+ for(a=0, mvert=me->mvert; a<me->totvert; a++, mvert++) {
+ Mat4MulVecfl(cd.curvespace, mvert->co);
+ DO_MINMAX(mvert->co, cd.dmin, cd.dmax);
+ }
- for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
- if(applyflag) calc_latt_deform(mvert->co);
- else {
- VECCOPY(fp, mvert->co);
- calc_latt_deform(fp);
- }
+ mvert= me->mvert;
+ for(a=0; a<me->totvert; a++, mvert++) {
+ calc_curve_deform(ob->parent, mvert->co, ob->trackflag, &cd);
+ /* move coord back to objectspace */
+ Mat4MulVecfl(cd.objectspace, mvert->co);
+ }
+ }
+ /* restore */
+ cu->flag = flag;
+ return 1;
+ }
+ else if(ob->parent->type==OB_LATTICE) {
+
+ init_latt_deform(ob->parent, ob);
+
+ if(ob->type==OB_MESH) {
+ me= ob->data;
+
+ mvert= me->mvert;
+ for(a=0; a<me->totvert; a++, mvert++) {
+ calc_latt_deform(mvert->co);
}
}
else if(ob->type==OB_MBALL) {
@@ -479,9 +627,6 @@ static int _object_deform(Object *ob, int applyflag)
}
}
end_latt_deform();
-
- boundbox_displist(ob);
-
return 1;
}
else if(ob->parent->type==OB_ARMATURE) {
@@ -495,97 +640,16 @@ static int _object_deform(Object *ob, int applyflag)
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(applyflag){
- calc_armature_deform(ob->parent, mvert->co, a);
- }
- else {
- VECCOPY(fp, mvert->co);
- calc_armature_deform(ob->parent, fp, a);
- }
+ for(a=0; a<me->totvert; a++, mvert++) {
+ calc_armature_deform(ob->parent, mvert->co, a);
}
-
break;
- default:
+ case OB_CURVE:
+ case OB_SURF:
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(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(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;
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index bd7cb626182..b4b8203355b 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -148,6 +148,16 @@ void update_base_layer(Object *ob)
}
}
+static void free_hooks(ListBase *lb)
+{
+ while(lb->first) {
+ ObHook *hook= lb->first;
+ if(hook->indexar) MEM_freeN(hook->indexar);
+ BLI_remlink(lb, hook);
+ MEM_freeN(hook);
+ }
+}
+
/* do not free object itself */
void free_object(Object *ob)
{
@@ -193,7 +203,9 @@ void free_object(Object *ob)
free_constraints(&ob->constraints);
free_constraint_channels(&ob->constraintChannels);
free_nlastrips(&ob->nlastrips);
-
+
+ free_hooks(&ob->hooks);
+
freedisplist(&ob->disp);
BPY_free_scriptlink(&ob->scriptlink);
@@ -210,6 +222,7 @@ void unlink_object(Object *ob)
Scene *sce;
Curve *cu;
Tex *tex;
+ ObHook *hook;
Group *group;
int a;
@@ -225,6 +238,9 @@ void unlink_object(Object *ob)
if(ob->type==OB_LATTICE) freedisplist(&obt->disp);
}
if(obt->track==ob) obt->track= NULL;
+ for(hook=obt->hooks.first; hook; hook= hook->next) {
+ if(hook->parent==ob) hook->parent= NULL;
+ }
if ELEM(obt->type, OB_CURVE, OB_FONT) {
cu= obt->data;
if(cu->bevobj==ob) cu->bevobj= NULL;
@@ -752,7 +768,8 @@ Object *copy_object(Object *ob)
id_us_plus((ID *)obn->action);
for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
- obn->disp.first= obn->disp.last= 0;
+ obn->disp.first= obn->disp.last= NULL;
+ obn->hooks.first= obn->hooks.last= NULL;
return obn;
}
@@ -969,7 +986,8 @@ void ob_parcurve(Object *ob, Object *par, float mat[][4])
if(cu->flag & CU_FOLLOW) {
quat= vectoquat(dir, ob->trackflag, ob->upflag);
-
+
+ /* the tilt */
Normalise(dir);
q[0]= (float)cos(0.5*vec[3]);
x1= (float)sin(0.5*vec[3]);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8da7ff687c8..a9a5b16b462 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2122,7 +2122,7 @@ static void lib_link_object(FileData *fd, Main *main)
bSensor *sens;
bController *cont;
bActuator *act;
-
+ ObHook *hook;
void *poin;
int warn=0, a;
@@ -2240,6 +2240,10 @@ static void lib_link_object(FileData *fd, Main *main)
}
lib_link_scriptlink(fd, &ob->id, &ob->scriptlink);
+
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ hook->parent= newlibadr(fd, ob->id.lib, hook->parent);
+ }
}
ob= ob->id.next;
}
@@ -2270,7 +2274,8 @@ static void direct_link_object(FileData *fd, Object *ob)
bSensor *sens;
bController *cont;
bActuator *act;
-
+ ObHook *hook;
+
ob->disp.first=ob->disp.last= 0;
ob->pose= newdataadr(fd, ob->pose);
@@ -2335,7 +2340,18 @@ static void direct_link_object(FileData *fd, Object *ob)
act= act->next;
}
- ob->bb= 0;
+ link_list(fd, &ob->hooks);
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ hook->indexar= newdataadr(fd, hook->indexar);
+ if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+ int a;
+ for(a=0; a<hook->totindex; a++) {
+ SWITCH_INT(hook->indexar[a]);
+ }
+ }
+ }
+
+ ob->bb= NULL;
}
/* ************ READ SCENE ***************** */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 94e2e804073..0bb8d378978 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -655,7 +655,8 @@ static void write_constraint_channels(WriteData *wd, ListBase *chanbase)
static void write_objects(WriteData *wd, ListBase *idbase)
{
Object *ob;
-
+ ObHook *hook;
+
ob= idbase->first;
while(ob) {
if(ob->id.us>0) {
@@ -677,6 +678,11 @@ static void write_objects(WriteData *wd, ListBase *idbase)
write_nlastrips(wd, &ob->nlastrips);
writestruct(wd, DATA, "PartDeflect", 1, ob->pd);
+
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ writestruct(wd, DATA, "ObHook", 1, hook);
+ writedata(wd, DATA, sizeof(int)*hook->totindex, hook->indexar);
+ }
}
ob= ob->id.next;
}
diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h
index e99ce2c625f..839bf4c6802 100644
--- a/source/blender/include/BDR_editcurve.h
+++ b/source/blender/include/BDR_editcurve.h
@@ -33,6 +33,7 @@
#ifndef BDR_EDITCURVE_H
#define BDR_EDITCURVE_H
+struct Object;
struct Curve;
struct Nurb;
struct BezTriple;
@@ -89,6 +90,7 @@ void add_primitiveNurb(int type);
void clear_tilt(void);
void clever_numbuts_curve(void);
int bezt_compare (const void *e1, const void *e2);
+void curve_changes_other_objects(struct Object *ob);
extern void undo_push_curve(char *name);
extern void undo_clear_curve(void);
diff --git a/source/blender/include/BDR_editobject.h b/source/blender/include/BDR_editobject.h
index 5b1fe2552aa..a00878448fa 100644
--- a/source/blender/include/BDR_editobject.h
+++ b/source/blender/include/BDR_editobject.h
@@ -119,6 +119,7 @@ void mirrormenu(void);
void mirror_edit(short mode);
void mirror_object(short mode);
void flag_edge_crease(void);
+void add_hook(void);
#endif /* BDR_EDITOBJECT_H */
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 54af18adfb3..2c83b50e6e3 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -209,11 +209,14 @@ void butspace_context_switch(SpaceButs *buts, struct Base *new);
#define B_ANIMBUTS 1500
#define B_RECALCPATH 1401
-
+#define B_TRACKBUTS 1402
+#define B_DEL_HOOK 1403
+#define B_CLR_HOOK 1404
#define B_PRINTSPEED 1413
#define B_PRINTLEN 1414
#define B_RELKEY 1415
+#define B_CURVECHECK 1416
/* this has MAX_EFFECT settings! Next free define is 1450... */
#define B_SELEFFECT 1430
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 59e91fa861b..bdf91f35a2f 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -174,6 +174,7 @@ typedef struct IpoCurve {
#define CU_FOLLOW 16
#define CU_UV_ORCO 32
#define CU_NOPUNOFLIP 64
+#define CU_STRETCH 128
/* spacemode */
#define CU_LEFT 0
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index ac6e75f03e5..2905b2eeb09 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -89,7 +89,6 @@ typedef struct PartDeflect {
float f_power; /* The power law - real gravitation is 2 (square) */
} PartDeflect;
-
typedef struct Object {
ID id;
@@ -191,7 +190,8 @@ typedef struct Object {
ListBase constraints;
ListBase nlastrips;
-
+ ListBase hooks;
+
PartDeflect *pd; /* particle deflector/attractor/collision data */
struct Life *life;
@@ -201,6 +201,24 @@ typedef struct Object {
float toonedge, smoothresh; /* smoothresh is phong interpolation ray_shadow correction in render */
} Object;
+typedef struct ObHook {
+ struct ObHook *next, *prev;
+
+ struct Object *parent;
+ float parentinv[4][4]; /* matrix making current transform unmodified */
+ float mat[4][4]; /* temp matrix while hooking */
+ float cent[3]; /* visualization of hook */
+ int pad;
+
+ char name[32];
+
+ int *indexar;
+ int totindex, curindex; /* curindex is cache for fast lookup */
+ short type, active; /* active is only first hook, for button menu */
+ float force;
+} ObHook;
+
+
/* this work object is defined in object.c */
extern Object workob;
diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c
index 3f5765c3fb5..25698bfe5ca 100644
--- a/source/blender/renderconverter/intern/convertBlenderScene.c
+++ b/source/blender/renderconverter/intern/convertBlenderScene.c
@@ -68,27 +68,27 @@
#include "DNA_meta_types.h"
#include "DNA_space_types.h"
-#include "BKE_mesh.h"
-#include "BKE_key.h"
+#include "BKE_anim.h"
+#include "BKE_armature.h"
#include "BKE_action.h"
#include "BKE_curve.h"
-#include "BKE_armature.h"
-#include "BKE_object.h"
-#include "BKE_texture.h"
-#include "BKE_material.h"
-#include "BKE_main.h"
-#include "BKE_mball.h"
-#include "BKE_anim.h"
-#include "BKE_global.h"
+#include "BKE_constraint.h"
+#include "BKE_displist.h"
+#include "BKE_deform.h"
#include "BKE_effect.h"
-#include "BKE_world.h"
+#include "BKE_global.h"
+#include "BKE_key.h"
#include "BKE_ipo.h"
#include "BKE_ika.h"
-#include "BKE_displist.h"
#include "BKE_lattice.h"
-#include "BKE_constraint.h"
-#include "BKE_utildefines.h"
+#include "BKE_material.h"
+#include "BKE_main.h"
+#include "BKE_mball.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
#include "BKE_subsurf.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
#include "BKE_world.h"
#include "render.h"
@@ -1247,8 +1247,8 @@ static void init_render_mesh(Object *ob)
me= ob->data;
- /* object_deform changes imat */
- do_puno= object_deform(ob);
+ /* object_deform changes imat! */
+ do_puno= mesh_modifier(ob, 's');
paf = give_parteff(ob);
if(paf) {
@@ -1299,8 +1299,6 @@ static void init_render_mesh(Object *ob)
if((me->subdivdone-1)!=me->subdivr) {
DispList *dlVerts;
- object_deform(ob);
-
dlVerts= find_displist(&ob->disp, DL_VERTS);
dlm= subsurf_make_dispListMesh_from_mesh(me, dlVerts?dlVerts->verts:NULL, me->subdivr, me->flag);
dl= MEM_callocN(sizeof(*dl), "dl");
@@ -1317,16 +1315,19 @@ static void init_render_mesh(Object *ob)
}
}
- if(dl==0 || dl->type!=DL_MESH) return;
- dlm= dl->mesh;
-
- mvert= dlm->mvert;
- totvert= dlm->totvert;
-
- if(need_orco) {
- make_orco_displist_mesh(ob, me->subdivr);
+ if(dl==NULL || dl->type!=DL_MESH); // here used to be a return, but why?
+ else {
+ dlm= dl->mesh;
+
+ mvert= dlm->mvert;
+ totvert= dlm->totvert;
+
+ if(need_orco) {
+ make_orco_displist_mesh(ob, me->subdivr);
+ }
+ ms= NULL; // no stick in displistmesh
}
- ms= NULL; // no stick in displistmesh
+
} else {
dlm= NULL;
mvert= me->mvert;
@@ -1527,7 +1528,8 @@ static void init_render_mesh(Object *ob)
}
if(do_puno) normalenrender(totverto, totvlako);
-
+
+ mesh_modifier(ob, 'e'); // end
}
/* ------------------------------------------------------------------------- */
@@ -1797,6 +1799,8 @@ static void init_render_surf(Object *ob)
if(cu->orco==0 && need_orco) make_orco_surf(cu);
orco= cu->orco;
+ curve_modifier(ob, 's');
+
/* make a complete new displist, the base-displist can be different */
displist.first= displist.last= 0;
nu= cu->nurb.first;
@@ -1840,6 +1844,9 @@ static void init_render_surf(Object *ob)
end_latt_deform();
}
+ /* note; deform will be included in modifier() later */
+ curve_modifier(ob, 'e');
+
if(ob->partype==PARSKEL && ob->parent && ob->parent->type==OB_ARMATURE) {
/* bArmature *arm= ob->parent->data; */
init_armature_deform(ob->parent, ob);
@@ -2162,6 +2169,8 @@ static void init_render_curve(Object *ob)
nu= cu->nurb.first;
if(nu==0) return;
+ curve_modifier(ob, 's');
+
/* test displist */
if(cu->disp.first==0) makeDispList(ob);
dl= cu->disp.first;
@@ -2234,6 +2243,9 @@ static void init_render_curve(Object *ob)
}
}
+ /* modifier() will get deform included later */
+ curve_modifier(ob, 'e');
+
if(ob->parent && ob->parent->type==OB_LATTICE) {
lt= ob->parent->data;
init_latt_deform(ob->parent, ob);
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index fb1bb652be3..8d40bb2307f 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1248,17 +1248,20 @@ static void editing_panel_curve_type(Object *ob, Curve *cu)
}
if(ob->type!=OB_SURF) {
-
+
if(ob->type==OB_CURVE) {
extern float prlen; // buttons_object.c, should be moved....
char str[32];
uiBlockBeginAlign(block);
- uiDefButS(block, NUM, B_RECALCPATH, "PathLen:", 600,50,150,19, &cu->pathlen, 1.0, 9000.0, 0, 0, "");
- uiDefButS(block, TOG|BIT|3, B_RECALCPATH, "CurvePath", 600,30,75,19 , &cu->flag, 0, 0, 0, 0, "");
- uiDefButS(block, TOG|BIT|4, REDRAWVIEW3D, "CurveFollow",675,30,75,19, &cu->flag, 0, 0, 0, 0, "");
+ uiDefButS(block, NUM, B_RECALCPATH, "PathLen:", 600,50,150,19, &cu->pathlen, 1.0, 9000.0, 0, 0, "If no speed Ipo was set, the amount of frames of the path");
+ uiDefButS(block, TOG|BIT|3, B_RECALCPATH, "CurvePath", 600,30,75,19 , &cu->flag, 0, 0, 0, 0, "Enables curve to become translation path");
+ uiDefButS(block, TOG|BIT|4, REDRAWVIEW3D, "CurveFollow",675,30,75,19, &cu->flag, 0, 0, 0, 0, "Makes curve path children to rotate along path");
+ uiDefButS(block, TOG|BIT|7, B_CURVECHECK, "CurveStretch", 600,10,150,19, &cu->flag, 0, 0, 0, 0, "Option for curve-deform: makes deformed child to stretch along entire path");
+
+ uiBlockEndAlign(block);
sprintf(str, "%.4f", prlen);
- uiDefBut(block, BUT, B_PRINTLEN, "PrintLen", 600,10,75,19, 0, 0, 0, 0, 0, "");
- uiDefBut(block, LABEL, 0, str, 675,10,75,19, 0, 1.0, 0, 0, 0, "");
+ uiDefBut(block, BUT, B_PRINTLEN, "PrintLen", 600,-10,75,19, 0, 0, 0, 0, 0, "");
+ uiDefBut(block, LABEL, 0, str, 675,-10,75,19, 0, 1.0, 0, 0, 0, "");
}
uiBlockBeginAlign(block);
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 4314b3fa408..29fa70a1644 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -72,6 +72,7 @@
#include "BDR_editcurve.h"
#include "BDR_editface.h"
#include "BDR_drawobject.h"
+
#include "BIF_butspace.h"
#include "mydevice.h"
@@ -1033,18 +1034,102 @@ void object_panel_draw(Object *ob)
}
+void object_panel_hooks(Object *ob)
+{
+ uiBlock *block;
+ ObHook *hook;
+ int tothook=0, nr, active;
+ char *cp;
+
+ block= uiNewBlock(&curarea->uiblocks, "object_panel_hooks", UI_EMBOSS, UI_HELV, curarea->win);
+ uiNewPanelTabbed("Draw", "Object");
+ if(uiNewPanel(curarea, block, "Hooks", "Object", 320, 0, 318, 204)==0) return;
+
+ if(ob->hooks.first==NULL) {
+ uiDefBut(block, LABEL, 0, "Add hooks in Editmode", 10,180,300,19, NULL, 0, 0, 0, 0, "");
+ return;
+ }
+
+ /* build menu */
+ for(hook= ob->hooks.first; hook; hook= hook->next) tothook++;
+
+ cp= MEM_callocN(32*tothook+32, "temp string");
+ strcpy(cp, "Active Hook %t|");
+
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+ strcat(cp, hook->name);
+ strcat(cp, " |");
+ }
+ /* active is stored in first hook */
+ hook= ob->hooks.first;
+ if(hook->active<1 || hook->active > tothook) hook->active= 1;
+ active= hook->active;
+
+ uiDefButS(block, MENU, B_REDR, cp, 10,180,150,19, &hook->active, 0, 0, 0, 0, "Set active hook");
+ MEM_freeN(cp);
+ for(nr=1, hook= ob->hooks.first; hook; hook= hook->next, nr++) {
+ if(nr==active) break;
+ }
+ if(hook==NULL) printf("error in object_panel_hooks\n");
+
+ uiBlockBeginAlign(block);
+ uiDefButC(block, TEX, B_REDR, "Name: ", 160,180,150,19, hook->name, 0, 32, 0, 0, "Set name of hook");
+ uiDefIDPoinBut(block, test_obpoin_but, B_CLR_HOOK, "Parent:", 160, 160, 150, 19, &hook->parent, "Parent Object for hook, also recalculates and clears offset");
+ uiDefButF(block, NUMSLI, B_MAKEDISP, "Force: ", 160,140,150,19, &hook->force, 0.0, 1.0, 100, 0, "Set force of hook");
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, BUT, B_DEL_HOOK, "Delete", 10,100,150,19, NULL, 0.0, 0.0, 0, 0, "Delete hook");
+ uiDefBut(block, BUT, B_CLR_HOOK, "Clear offset", 160,100,150,19, NULL, 0.0, 0.0, 0, 0, "Recalculate and clear offset (transform) of hook");
+}
void do_object_panels(unsigned short event)
{
Object *ob;
+ ObHook *hook;
Effect *eff;
ob= OBACT;
switch(event) {
-
+ case B_TRACKBUTS:
+ ob= OBACT;
+ if(ob && ob->parent && ob->parent->type==OB_CURVE) freedisplist(&ob->disp);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+ case B_DEL_HOOK:
+ hook= ob->hooks.first;
+ if(hook) {
+ int active= hook->active, nr;
+ for(nr=1, hook=ob->hooks.first; hook; hook=hook->next, nr++) {
+ if(active==nr) break;
+ }
+ if(hook) {
+ BLI_remlink(&ob->hooks, hook);
+ if(hook->indexar) MEM_freeN(hook->indexar);
+ MEM_freeN(hook);
+ }
+ freedisplist(&ob->disp);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+ }
+ break;
+ case B_CLR_HOOK:
+ hook= ob->hooks.first;
+ if(hook) {
+ int active= hook->active, nr;
+ for(nr=1, hook=ob->hooks.first; hook; hook=hook->next, nr++) {
+ if(active==nr) break;
+ }
+ if(hook && hook->parent) {
+ Mat4Invert(hook->parent->imat, hook->parent->obmat);
+ /* apparently this call goes from right to left... */
+ Mat4MulSerie(hook->parentinv, hook->parent->imat, ob->obmat, NULL,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ }
+ break;
case B_RECALCPATH:
calc_curvepath(OBACT);
allqueue(REDRAWVIEW3D, 0);
@@ -1079,7 +1164,11 @@ void do_object_panels(unsigned short event)
allqueue(REDRAWBUTSOBJECT, 0);
allqueue(REDRAWIPO, 0);
break;
-
+ case B_CURVECHECK:
+ curve_changes_other_objects(OBACT);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
+
default:
if(event>=B_SELEFFECT && event<B_SELEFFECT+MAX_EFFECT) {
ob= OBACT;
@@ -1101,7 +1190,6 @@ void do_object_panels(unsigned short event)
}
-
static void object_panel_anim(Object *ob)
{
uiBlock *block;
@@ -1111,12 +1199,12 @@ static void object_panel_anim(Object *ob)
if(uiNewPanel(curarea, block, "Anim settings", "Object", 0, 0, 318, 204)==0) return;
uiBlockBeginAlign(block);
- uiDefButC(block, ROW,REDRAWVIEW3D,"TrackX", 24,190,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
- uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 85,190,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
- uiDefButC(block, ROW,REDRAWVIEW3D,"Z", 104,190,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
- uiDefButC(block, ROW,REDRAWVIEW3D,"-X", 124,190,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
- uiDefButC(block, ROW,REDRAWVIEW3D,"-Y", 150,190,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
- uiDefButC(block, ROW,REDRAWVIEW3D,"-Z", 178,190,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_TRACKBUTS,"TrackX", 24,190,59,19, &ob->trackflag, 12.0, 0.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_TRACKBUTS,"Y", 85,190,19,19, &ob->trackflag, 12.0, 1.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_TRACKBUTS,"Z", 104,190,19,19, &ob->trackflag, 12.0, 2.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_TRACKBUTS,"-X", 124,190,24,19, &ob->trackflag, 12.0, 3.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_TRACKBUTS,"-Y", 150,190,24,19, &ob->trackflag, 12.0, 4.0, 0, 0, "Specify the axis that points to another object");
+ uiDefButC(block, ROW,B_TRACKBUTS,"-Z", 178,190,24,19, &ob->trackflag, 12.0, 5.0, 0, 0, "Specify the axis that points to another object");
uiBlockBeginAlign(block);
uiDefButC(block, ROW,REDRAWVIEW3D,"UpX", 226,190,45,19, &ob->upflag, 13.0, 0.0, 0, 0, "Specify the axis that points up");
uiDefButC(block, ROW,REDRAWVIEW3D,"Y", 274,190,20,19, &ob->upflag, 13.0, 1.0, 0, 0, "Specify the axis that points up");
@@ -1485,6 +1573,7 @@ void object_panels()
object_panel_anim(ob);
object_panel_draw(ob);
+ object_panel_hooks(ob);
object_panel_constraint();
if(ob->type==OB_MESH) {
object_panel_effects(ob);
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index 127ba5d5582..935901548d4 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -74,15 +74,16 @@
#include "BKE_utildefines.h"
#include "BKE_curve.h"
#include "BKE_constraint.h" // for the get_constraint_target function
-#include "BKE_object.h"
-#include "BKE_global.h"
+#include "BKE_deform.h" // lattice_modifier()
#include "BKE_displist.h"
-#include "BKE_material.h"
-#include "BKE_mball.h"
-#include "BKE_ipo.h"
-#include "BKE_mesh.h"
#include "BKE_effect.h"
+#include "BKE_global.h"
+#include "BKE_ipo.h"
#include "BKE_lattice.h"
+#include "BKE_mesh.h"
+#include "BKE_material.h"
+#include "BKE_mball.h"
+#include "BKE_object.h"
#include "BIF_gl.h"
#include "BIF_mywindow.h"
@@ -861,6 +862,7 @@ static void drawlattice(Object *ob)
cpack(0x004000);
}
else {
+ lattice_modifier(ob, 's');
bp= lt->def;
}
@@ -950,6 +952,8 @@ static void drawlattice(Object *ob)
if(G.zbuf) glEnable(GL_DEPTH_TEST);
}
+ else lattice_modifier(ob, 'e');
+
}
/* ***************** ******************** */
@@ -3701,6 +3705,33 @@ static void draw_extra_wire(Object *ob)
}
}
+/* should be called in view space */
+static void draw_hooks(Object *ob)
+{
+ ObHook *hook;
+ float vec[3];
+
+ for(hook= ob->hooks.first; hook; hook= hook->next) {
+
+ VecMat4MulVecfl(vec, ob->obmat, hook->cent);
+ if(hook->parent) {
+ setlinestyle(3);
+ glBegin(GL_LINES);
+ glVertex3fv(hook->parent->obmat[3]);
+ glVertex3fv(vec);
+ glEnd();
+ setlinestyle(0);
+ }
+
+ glPointSize(3.0);
+ bglBegin(GL_POINTS);
+ bglVertex3fv(vec);
+ bglEnd();
+ glPointSize(1.0);
+
+ }
+}
+
void draw_object(Base *base)
{
PartEff *paf;
@@ -3873,6 +3904,17 @@ void draw_object(Base *base)
}
}
+ /* exception for mesh..., needs to be here for outline draw */
+ if(ob->type==OB_MESH) {
+ me= ob->data;
+ /* check for need for displist (it's zero when parent, key, or hook changed) */
+ if(ob->disp.first==NULL) {
+ if(ob->parent && ob->partype==PARSKEL) makeDispList(ob);
+ else if(ob->hooks.first) makeDispList(ob);
+ else if(mesh_uses_displist(me)) makeDispList(ob);
+ }
+ }
+
/* draw outline for selected solid objects */
if(G.vd->flag & V3D_SELECT_OUTLINE) {
if(dt>OB_WIRE && ob!=G.obedit && (G.f & G_BACKBUFSEL)==0) {
@@ -3886,17 +3928,6 @@ void draw_object(Base *base)
case OB_MESH:
me= ob->data;
-#if 0
- /* this is a source of great slowness */
- /* Force a refresh of the display list if the parent is an armature */
- if (ob->parent && ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL){
-#if 0 /* Turn this on if there are problems with deformation lag */
- where_is_armature (ob->parent);
-#endif
- if (ob != G.obedit)
- makeDispList (ob);
- }
-#endif
if(base->flag & OB_RADIO);
else if(ob==G.obedit || (G.obedit && ob->data==G.obedit->data)) {
if(dt<=OB_WIRE) drawmeshwire(ob);
@@ -4013,7 +4044,7 @@ void draw_object(Base *base)
if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);
if((dtx & OB_DRAWWIRE) && dt>=OB_SOLID) draw_extra_wire(ob);
}
-
+
if(dt<OB_SHADED) {
if((ob->gameflag & OB_ACTOR) && (ob->gameflag & OB_DYNAMIC)) {
float tmat[4][4], imat[4][4], vec[3];
@@ -4040,6 +4071,9 @@ void draw_object(Base *base)
if((G.f & (G_BACKBUFSEL+G_PICKSEL))==0) {
ListBase *list;
+ /* draw hook center and offset line */
+ if(ob->hooks.first && ob!=G.obedit) draw_hooks(ob);
+
/* help lines and so */
if(ob->parent && (ob->parent->lay & G.vd->lay)) {
setlinestyle(3);
diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c
index f6fc8500642..1b2c202ae55 100644
--- a/source/blender/src/editcurve.c
+++ b/source/blender/src/editcurve.c
@@ -450,6 +450,8 @@ void separate_nurb()
G.obedit= 0; /* displists behave different in edit mode */
makeDispList(OBACT); /* this is the separated one */
+
+ curve_changes_other_objects(oldob);
G.obedit= oldob;
BASACT= oldbase;
@@ -1053,6 +1055,8 @@ void switchdirectionNurb2(void)
}
makeDispList(G.obedit);
+ curve_changes_other_objects(G.obedit);
+
allqueue(REDRAWVIEW3D, 0);
}
@@ -1714,6 +1718,8 @@ void subdivideNurb()
makeDispList(G.obedit);
+ curve_changes_other_objects(G.obedit);
+
countall();
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
@@ -2298,7 +2304,10 @@ void merge_nurb()
countall();
lastnu= NULL;
+
makeDispList(G.obedit);
+ curve_changes_other_objects(G.obedit);
+
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
@@ -2455,6 +2464,8 @@ void addsegment_nurb()
lastnu= NULL; /* for selected */
makeDispList(G.obedit);
+ curve_changes_other_objects(G.obedit);
+
countall();
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
@@ -2653,6 +2664,24 @@ void spinNurb(float *dvec, short mode)
}
}
+void curve_changes_other_objects(Object *ob)
+{
+ Base *base= FIRSTBASE;
+ while(base) {
+ if(base->lay & G.vd->lay) {
+ if(base->object->parent==ob && base->object->partype==PARSKEL)
+ freedisplist(&base->object->disp);
+
+ if(base->object->type==OB_CURVE) {
+ Curve *cu= base->object->data;
+ if(ob==cu->bevobj || ob==cu->taperobj)
+ makeDispList(base->object);
+ }
+ }
+ base= base->next;
+ }
+}
+
void addvert_Nurb(int mode)
{
Nurb *nu;
@@ -2787,17 +2816,7 @@ void addvert_Nurb(int mode)
if(mode!='e') {
/* dependencies with other objects, should become event */
- Base *base= FIRSTBASE;
- while(base) {
- if(base->lay & G.vd->lay) {
- if(base->object->type==OB_CURVE) {
- Curve *cu= base->object->data;
- if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
- makeDispList(base->object);
- }
- }
- base= base->next;
- }
+ curve_changes_other_objects(G.obedit);
}
}
@@ -2941,6 +2960,8 @@ void makecyclicNurb()
nu= nu->next;
}
makeDispList(G.obedit);
+ curve_changes_other_objects(G.obedit);
+
}
void selectconnected_nurb()
@@ -3325,6 +3346,8 @@ void delNurb()
countall();
makeDispList(G.obedit);
+ curve_changes_other_objects(G.obedit);
+
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
@@ -3880,7 +3903,8 @@ void add_primitiveCurve(int stype)
BLI_addtail(&editNurb, nu);
makeDispList(G.obedit);
-
+ curve_changes_other_objects(G.obedit);
+
countall();
allqueue(REDRAWALL, 0);
}
@@ -4061,7 +4085,6 @@ void undo_push_curve(char *name)
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at previous step */
void undo_curve_step(int step)
{
- Base *base;
UndoElem *uel, *next;
/* prevent undo to happen on wrong object */
@@ -4108,19 +4131,7 @@ void undo_curve_step(int step)
lastnu= NULL; /* for selected */
makeDispList(G.obedit);
-
- /* dependencies with other objects */
- base= FIRSTBASE;
- while(base) {
- if(base->lay & G.vd->lay) {
- if(base->object->type==OB_CURVE) {
- Curve *cu= base->object->data;
- if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
- makeDispList(base->object);
- }
- }
- base= base->next;
- }
+ curve_changes_other_objects(G.obedit);
countall();
allqueue(REDRAWVIEW3D, 0);
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index b3fdef709ec..a8399aa0bc7 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -224,14 +224,11 @@ void free_and_unlink_base(Base *base)
void delete_obj(int ok)
{
Base *base;
-extern int undo_push(char *);
if(G.obpose) return;
if(G.obedit) return;
if(G.scene->id.lib) return;
-//if (undo_push("Erase")) return;
-
base= FIRSTBASE;
while(base) {
Base *nbase= base->next;
@@ -260,6 +257,381 @@ extern int undo_push(char *);
allqueue(REDRAWNLA, 0);
}
+int return_editmesh_indexar(int **indexar, float *cent)
+{
+ EditMesh *em = G.editMesh;
+ EditVert *eve;
+ int *index, nr, totvert=0;
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->f & SELECT) totvert++;
+ }
+ if(totvert==0) return 0;
+
+ *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
+ nr= 0;
+ cent[0]= cent[1]= cent[2]= 0.0;
+
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->f & SELECT) {
+ *index= nr; index++;
+ VecAddf(cent, cent, eve->co);
+ }
+ nr++;
+ }
+
+ VecMulf(cent, 1.0/(float)totvert);
+
+ return totvert;
+}
+
+static void select_editmesh_hook(ObHook *hook)
+{
+ EditMesh *em = G.editMesh;
+ EditVert *eve;
+ int index=0, nr=0;
+
+ for(eve= em->verts.first; eve; eve= eve->next, nr++) {
+ if(nr==hook->indexar[index]) {
+ eve->f |= SELECT;
+ if(index < hook->totindex-1) index++;
+ }
+ }
+}
+
+int return_editlattice_indexar(int **indexar, float *cent)
+{
+ BPoint *bp;
+ int *index, nr, totvert=0, a;
+
+ // count
+ a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+ bp= editLatt->def;
+ while(a--) {
+ if(bp->f1 & SELECT) {
+ if(bp->hide==0) totvert++;
+ }
+ bp++;
+ }
+
+ if(totvert==0) return 0;
+
+ *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
+ nr= 0;
+ cent[0]= cent[1]= cent[2]= 0.0;
+
+ a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+ bp= editLatt->def;
+ while(a--) {
+ if(bp->f1 & SELECT) {
+ if(bp->hide==0) {
+ *index= nr; index++;
+ VecAddf(cent, cent, bp->vec);
+ }
+ }
+ bp++;
+ nr++;
+ }
+
+ VecMulf(cent, 1.0/(float)totvert);
+
+ return totvert;
+}
+
+static void select_editlattice_hook(ObHook *hook)
+{
+ BPoint *bp;
+ int index=0, nr=0, a;
+
+ // count
+ a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
+ bp= editLatt->def;
+ while(a--) {
+ if(hook->indexar[index]==nr) {
+ bp->f1 |= SELECT;
+ if(index < hook->totindex-1) index++;
+ }
+ nr++;
+ bp++;
+ }
+}
+
+int return_editcurve_indexar(int **indexar, float *cent)
+{
+ extern ListBase editNurb;
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int *index, a, nr, totvert=0;
+
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if((nu->type & 7)==CU_BEZIER) {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--) {
+ if(bezt->f1 & SELECT) totvert++;
+ if(bezt->f2 & SELECT) totvert++;
+ if(bezt->f3 & SELECT) totvert++;
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+ while(a--) {
+ if(bp->f1 & SELECT) totvert++;
+ bp++;
+ }
+ }
+ }
+ if(totvert==0) return 0;
+
+ *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
+ nr= 0;
+ cent[0]= cent[1]= cent[2]= 0.0;
+
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if((nu->type & 7)==CU_BEZIER) {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--) {
+ if(bezt->f1 & SELECT) {
+ *index= nr; index++;
+ VecAddf(cent, cent, bezt->vec[0]);
+ }
+ nr++;
+ if(bezt->f2 & SELECT) {
+ *index= nr; index++;
+ VecAddf(cent, cent, bezt->vec[1]);
+ }
+ nr++;
+ if(bezt->f3 & SELECT) {
+ *index= nr; index++;
+ VecAddf(cent, cent, bezt->vec[2]);
+ }
+ nr++;
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+ while(a--) {
+ if(bp->f1 & SELECT) {
+ *index= nr; index++;
+ VecAddf(cent, cent, bp->vec);
+ }
+ nr++;
+ bp++;
+ }
+ }
+ }
+
+ VecMulf(cent, 1.0/(float)totvert);
+
+ return totvert;
+}
+
+static void select_editcurve_hook(ObHook *hook)
+{
+ extern ListBase editNurb;
+ Nurb *nu;
+ BPoint *bp;
+ BezTriple *bezt;
+ int index=0, a, nr=0;
+
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if((nu->type & 7)==CU_BEZIER) {
+ bezt= nu->bezt;
+ a= nu->pntsu;
+ while(a--) {
+ if(nr == hook->indexar[index]) {
+ bezt->f1 |= SELECT;
+ if(index<hook->totindex-1) index++;
+ }
+ nr++;
+ if(nr == hook->indexar[index]) {
+ bezt->f2 |= SELECT;
+ if(index<hook->totindex-1) index++;
+ }
+ nr++;
+ if(nr == hook->indexar[index]) {
+ bezt->f3 |= SELECT;
+ if(index<hook->totindex-1) index++;
+ }
+ nr++;
+
+ bezt++;
+ }
+ }
+ else {
+ bp= nu->bp;
+ a= nu->pntsu*nu->pntsv;
+ while(a--) {
+ if(nr == hook->indexar[index]) {
+ bp->f1 |= SELECT;
+ if(index<hook->totindex-1) index++;
+ }
+ nr++;
+ bp++;
+ }
+ }
+ }
+}
+
+void add_hook(void)
+{
+ Object *ob=NULL;
+ ObHook *hook=NULL;
+ float cent[3];
+ int tot=0, *indexar, mode;
+
+ if(G.obedit==NULL) return;
+
+ if(G.obedit->hooks.first)
+ mode= pupmenu("Hooks %t|Add Hook, To New Empty %x1|Add Hook, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
+ else
+ mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
+
+ if(mode<1) return;
+
+ /* preconditions */
+
+ if(mode==2) { // selected object
+ Base *base= FIRSTBASE;
+ while(base) {
+ if TESTBASELIB(base) {
+ if(base!=BASACT) {
+ ob= base->object;
+ break;
+ }
+ }
+ base= base->next;
+ }
+ if(ob==NULL) {
+ error("Requires selected Object");
+ return;
+ }
+ }
+ else if(mode!=1) {
+ int maxlen=0, a, nr;
+ char *cp;
+
+ // make pupmenu with hooks
+ for(hook= G.obedit->hooks.first; hook; hook= hook->next) maxlen+=32;
+
+ if(maxlen==0) {
+ error("Object has no hooks yet");
+ return;
+ }
+
+ cp= MEM_callocN(maxlen+32, "temp string");
+ if(mode==3) strcpy(cp, "Remove %t|");
+ else if(mode==4) strcpy(cp, "Reassign %t|");
+ else if(mode==5) strcpy(cp, "Select %t|");
+ else if(mode==6) strcpy(cp, "Clear Offset %t|");
+
+ for(hook= G.obedit->hooks.first; hook; hook= hook->next) {
+ strcat(cp, hook->name);
+ strcat(cp, " |");
+ }
+
+ nr= pupmenu(cp);
+ MEM_freeN(cp);
+
+ if(nr<1) return;
+
+ a= 1;
+ for(hook= G.obedit->hooks.first; hook; hook= hook->next, a++) {
+ if(a==nr) break;
+ }
+ ob= hook->parent;
+ }
+
+ /* do it, new hooks or reassign */
+ if(mode==1 || mode==2 || mode==4) {
+
+ switch(G.obedit->type) {
+ case OB_MESH:
+ tot= return_editmesh_indexar(&indexar, cent);
+ break;
+ case OB_CURVE:
+ case OB_SURF:
+ tot= return_editcurve_indexar(&indexar, cent);
+ break;
+ case OB_LATTICE:
+ tot= return_editlattice_indexar(&indexar, cent);
+ break;
+ }
+
+ if(tot==0) {
+ error("Requires selected vertices");
+ }
+ else {
+
+ if(mode==1) {
+ Base *base= BASACT;
+
+ ob= add_object(OB_EMPTY);
+ /* transform cent to global coords for loc */
+ VecMat4MulVecfl(ob->loc, G.obedit->obmat, cent);
+
+ /* restore, add_object sets active */
+ BASACT= base;
+ }
+ /* if mode is 2 or 4, ob has been set */
+
+ /* new hook */
+ if(mode==1 || mode==2) {
+ hook= MEM_callocN(sizeof(ObHook), "new hook");
+ BLI_addtail(&G.obedit->hooks, hook);
+ strncpy(hook->name, ob->id.name+2, 30);
+ hook->force= 1.0;
+ }
+ else MEM_freeN(hook->indexar); // reassign, hook was set
+
+ hook->parent= ob;
+ hook->indexar= indexar;
+ VECCOPY(hook->cent, cent);
+ hook->totindex= tot;
+
+ if(mode==1 || mode==2) {
+ /* matrix calculus */
+ /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
+ /* (parentinv ) */
+
+ where_is_object(ob);
+
+ Mat4Invert(ob->imat, ob->obmat);
+ /* apparently this call goes from right to left... */
+ Mat4MulSerie(hook->parentinv, ob->imat, G.obedit->obmat, NULL,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+ }
+ }
+ else if(mode==3) { // remove
+ BLI_remlink(&G.obedit->hooks, hook);
+ MEM_freeN(hook->indexar);
+ MEM_freeN(hook);
+ }
+ else if(mode==5) { // select
+ if(G.obedit->type==OB_MESH) select_editmesh_hook(hook);
+ else if(G.obedit->type==OB_LATTICE) select_editlattice_hook(hook);
+ else if(G.obedit->type==OB_CURVE) select_editcurve_hook(hook);
+ else if(G.obedit->type==OB_SURF) select_editcurve_hook(hook);
+ }
+ else if(mode==6) { // clear offset
+ where_is_object(ob); // ob is hook->parent
+
+ Mat4Invert(ob->imat, ob->obmat);
+ /* this call goes from right to left... */
+ Mat4MulSerie(hook->parentinv, ob->imat, G.obedit->obmat, NULL,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSOBJECT, 0);
+}
void make_track(void)
{
@@ -463,6 +835,7 @@ void clear_track(void)
void clear_object(char mode)
{
Base *base;
+ Object *ob;
float *v1, *v3, mat[3][3];
if(G.obedit) return;
@@ -492,28 +865,30 @@ void clear_object(char mode)
base= FIRSTBASE;
while(base) {
if TESTBASELIB(base) {
+ ob= base->object;
+
if(mode=='r') {
- memset(base->object->rot, 0, 3*sizeof(float));
- memset(base->object->drot, 0, 3*sizeof(float));
- QuatOne(base->object->quat);
- QuatOne(base->object->dquat);
+ memset(ob->rot, 0, 3*sizeof(float));
+ memset(ob->drot, 0, 3*sizeof(float));
+ QuatOne(ob->quat);
+ QuatOne(ob->dquat);
}
else if(mode=='g') {
- memset(base->object->loc, 0, 3*sizeof(float));
- memset(base->object->dloc, 0, 3*sizeof(float));
+ memset(ob->loc, 0, 3*sizeof(float));
+ memset(ob->dloc, 0, 3*sizeof(float));
}
else if(mode=='s') {
- memset(base->object->dsize, 0, 3*sizeof(float));
- base->object->size[0]= 1.0;
- base->object->size[1]= 1.0;
- base->object->size[2]= 1.0;
+ memset(ob->dsize, 0, 3*sizeof(float));
+ ob->size[0]= 1.0;
+ ob->size[1]= 1.0;
+ ob->size[2]= 1.0;
}
else if(mode=='o') {
- if(base->object->parent) {
- v1= base->object->loc;
- v3= base->object->parentinv[3];
+ if(ob->parent) {
+ v1= ob->loc;
+ v3= ob->parentinv[3];
- Mat3CpyMat4(mat, base->object->parentinv);
+ Mat3CpyMat4(mat, ob->parentinv);
VECCOPY(v3, v1);
v3[0]= -v3[0];
v3[1]= -v3[1];
@@ -521,6 +896,11 @@ void clear_object(char mode)
Mat3MulVecfl(mat, v3);
}
}
+
+ if(ob->parent && ob->partype==PARSKEL)
+ freedisplist(&ob->disp);
+ else if(ob->hooks.first)
+ freedisplist(&ob->disp);
}
base= base->next;
}
@@ -768,11 +1148,17 @@ void make_parent(void)
bConstraint *con;
bFollowPathConstraint *data;
- mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2");
- if (mode == 0){
+ mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3");
+ if(mode==0){
return;
}
- else if (mode == 2){
+ else if(mode==1) {
+ mode= PAROBJECT;
+ }
+ else if(mode==3) {
+ mode= PARSKEL;
+ }
+ else if(mode==2) {
base= FIRSTBASE;
while(base) {
@@ -936,6 +1322,8 @@ void make_parent(void)
}
else {
+ /* the ifs below are horrible code (ton) */
+
if(par->type==OB_IKA){
base->object->partype= mode;
base->object->par1= limbnr;
@@ -947,14 +1335,17 @@ void make_parent(void)
else
base->object->parsubstr[0]=0;
}
-
- else if(qual & LR_ALTKEY) {
- base->object->partype= PARVERT1;
- }
else {
- base->object->partype= PAROBJECT;
+ if(qual & LR_ALTKEY) {
+ base->object->partype= PARVERT1;
+ }
+ else if(par->type==OB_CURVE) {
+ base->object->partype= mode;
+ }
+ else {
+ base->object->partype= PAROBJECT;
+ }
}
-
base->object->parent= par;
/* calculate inverse parent matrix? */
@@ -983,7 +1374,7 @@ void make_parent(void)
}
if(par->type==OB_LATTICE) makeDispList(base->object);
- if(par->type==OB_IKA && mode==PARSKEL) makeDispList(base->object);
+ if(par->type==OB_CURVE && mode==PARSKEL) makeDispList(base->object);
if(par->type==OB_ARMATURE && mode == PARSKEL){
verify_defgroups(base->object);
makeDispList(base->object);
@@ -3100,8 +3491,18 @@ static void setbaseflags_for_editing(int mode) /* 0,'g','r','s' */
base->flag= BA_PARSEL
*/
- GHash *object_to_base_hash= NULL; /* built on demand, see below - zr */
+ GHash *object_to_base_hash= NULL;
Base *base;
+
+ /* moved to start of function, it is needed for hooks now too */
+ if (!object_to_base_hash) {
+ Base *b;
+ object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+
+ for (b= FIRSTBASE; b; b= b->next)
+ BLI_ghash_insert(object_to_base_hash, b->object, b);
+ }
+
copy_baseflags();
@@ -3133,14 +3534,36 @@ static void setbaseflags_for_editing(int mode) /* 0,'g','r','s' */
if(ika->parent && parsel) base->flag |= BA_WHERE_UPDATE;
}
+ if(ob->hooks.first) {
+ Base *b;
+ ObHook *hook= ob->hooks.first;
+
+ while(hook) {
+ if(hook->parent) {
+ Object *parsel= is_a_parent_selected(hook->parent);
+
+ b= BLI_ghash_lookup(object_to_base_hash, hook->parent);
+ if(parsel || ((base->flag | b->flag) & (SELECT | BA_PARSEL)) ) {
+ base->flag |= BA_DISP_UPDATE;
+ }
+ }
+ hook= hook->next;
+ }
+ }
+
+ if(ob->parent && ob->parent->type==OB_LATTICE)
+ if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE;
+
if(base->flag & (SELECT | BA_PARSEL)) {
base->flag |= BA_WHERE_UPDATE;
if(ob->parent) {
if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE;
- if(ob->parent->type==OB_IKA && ob->partype==PARSKEL) base->flag |= BA_DISP_UPDATE;
- if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) base->flag |= BA_DISP_UPDATE;
+ else if(ob->partype==PARSKEL) {
+ if ELEM3(ob->parent->type, OB_IKA, OB_CURVE, OB_ARMATURE)
+ base->flag |= BA_DISP_UPDATE;
+ }
}
if(ob->track) {
;
@@ -3151,16 +3574,6 @@ static void setbaseflags_for_editing(int mode) /* 0,'g','r','s' */
if(ob->type==OB_MBALL) {
Base *b;
- /* Only bother building the object to base
- * hash if we are going to be needing it... - zr
- */
- if (!object_to_base_hash) {
- object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
-
- for (b= FIRSTBASE; b; b= b->next)
- BLI_ghash_insert(object_to_base_hash, b->object, b);
- }
-
b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob));
b->flag |= BA_DISP_UPDATE;
}
@@ -3693,14 +4106,16 @@ void special_trans_update(int keyflags)
if(G.obedit) {
if(G.obedit->type==OB_CURVE) {
cu= G.obedit->data;
- if(cu->flag & CU_3D) makeBevelList(G.obedit);
+ makeBevelList(G.obedit); // might be needed for deform
calc_curvepath(G.obedit);
base= FIRSTBASE;
while(base) {
if(base->lay & G.vd->lay) {
- if(base->object->type==OB_CURVE) {
+ if(base->object->parent==G.obedit && base->object->partype==PARSKEL)
+ makeDispList(base->object);
+ else if(base->object->type==OB_CURVE) {
Curve *cu= base->object->data;
if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
makeDispList(base->object);
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 6300139888c..64a62af930f 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -1127,7 +1127,9 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case HKEY:
if(G.obedit) {
if(G.obedit->type==OB_MESH) {
- if(G.qual==LR_ALTKEY)
+ if(G.qual==LR_CTRLKEY)
+ add_hook();
+ else if(G.qual==LR_ALTKEY)
reveal_mesh();
else if((G.qual==LR_SHIFTKEY))
hide_mesh(1);
@@ -1135,7 +1137,9 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
hide_mesh(0);
}
else if(G.obedit->type== OB_SURF) {
- if(G.qual==LR_ALTKEY)
+ if(G.qual==LR_CTRLKEY)
+ add_hook();
+ else if(G.qual==LR_ALTKEY)
revealNurb();
else if((G.qual==LR_SHIFTKEY))
hideNurb(1);
@@ -1143,17 +1147,24 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
hideNurb(0);
}
else if(G.obedit->type==OB_CURVE) {
- undo_push_curve("Handle change");
if(G.qual==LR_CTRLKEY)
- autocalchandlesNurb_all(1); /* flag=1, selected */
- else if((G.qual==LR_SHIFTKEY))
- sethandlesNurb(1);
- else if((G.qual==0))
- sethandlesNurb(3);
-
- makeDispList(G.obedit);
-
- allqueue(REDRAWVIEW3D, 0);
+ add_hook();
+ else {
+ undo_push_curve("Handle change");
+ if(G.qual==LR_CTRLKEY)
+ autocalchandlesNurb_all(1); /* flag=1, selected */
+ else if((G.qual==LR_SHIFTKEY))
+ sethandlesNurb(1);
+ else if((G.qual==0))
+ sethandlesNurb(3);
+
+ makeDispList(G.obedit);
+
+ allqueue(REDRAWVIEW3D, 0);
+ }
+ }
+ else if(G.obedit->type==OB_LATTICE) {
+ if(G.qual==LR_CTRLKEY) add_hook();
}
}
else if(G.f & G_FACESELECT)