Stretch To constraint

Read today's meeting minutes for a description.

Bjornmose: We'll need some example and screenshots for the dev pages of blender3d.org. If you can do some, neat, if not, I'll do them.

Matt, Emilie and Chris: Please review UI addition. Pixel alignement and all that fun stuff has not be overly looked for (though I did some cleaning by adding alignment blocks).
This commit is contained in:
2004-09-05 20:21:16 +00:00
parent 81e960d1c4
commit ae9347662b
7 changed files with 316 additions and 48 deletions

View File

@@ -122,6 +122,12 @@ char constraint_has_target (bConstraint *con) {
if (data->tar) if (data->tar)
return 1; return 1;
} }
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = con->data;
if (data->tar)
return 1;
}
break; break;
} }
// Unknown types or CONSTRAINT_TYPE_NULL or no target // Unknown types or CONSTRAINT_TYPE_NULL or no target
@@ -130,54 +136,59 @@ char constraint_has_target (bConstraint *con) {
Object *get_constraint_target(bConstraint *con) Object *get_constraint_target(bConstraint *con)
{ {
/* /*
* If the target for this constraint is target, return a pointer * If the target for this constraint is target, return a pointer
* to the name for this constraints subtarget ... NULL otherwise * to the name for this constraints subtarget ... NULL otherwise
*/ */
switch (con->type) { switch (con->type) {
case CONSTRAINT_TYPE_ACTION:
case CONSTRAINT_TYPE_ACTION:
{ {
bActionConstraint *data = con->data; bActionConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_LOCLIKE: case CONSTRAINT_TYPE_LOCLIKE:
{ {
bLocateLikeConstraint *data = con->data; bLocateLikeConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_ROTLIKE: case CONSTRAINT_TYPE_ROTLIKE:
{ {
bRotateLikeConstraint *data = con->data; bRotateLikeConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_KINEMATIC: case CONSTRAINT_TYPE_KINEMATIC:
{ {
bKinematicConstraint *data = con->data; bKinematicConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_TRACKTO: case CONSTRAINT_TYPE_TRACKTO:
{ {
bTrackToConstraint *data = con->data; bTrackToConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_LOCKTRACK: case CONSTRAINT_TYPE_LOCKTRACK:
{ {
bLockTrackConstraint *data = con->data; bLockTrackConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_FOLLOWPATH: case CONSTRAINT_TYPE_FOLLOWPATH:
{ {
bFollowPathConstraint *data = con->data; bFollowPathConstraint *data = con->data;
return data->tar; return data->tar;
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = con->data;
return (data->tar);
}
break;
} }
return NULL; return NULL;
@@ -310,6 +321,18 @@ void *new_constraint_data (short type)
result = data; result = data;
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
data = MEM_callocN(sizeof(bStretchToConstraint), "StretchToConstraint");
data->volmode = 0;
data->plane = 0;
data->orglength = 0.0;
data->bulge = 1.0;
result = data;
}
break;
default: default:
result = NULL; result = NULL;
break; break;
@@ -722,6 +745,21 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
Mat4One (mat); Mat4One (mat);
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
data = (bStretchToConstraint*)con->data;
if (data->tar){
where_is_object_time (data->tar, ctime);
constraint_target_to_mat4(data->tar, data->subtarget, mat, size, ctime);
valid = 1;
}
else
Mat4One (mat);
}
break;
default: default:
Mat4One(mat); Mat4One(mat);
break; break;
@@ -796,6 +834,15 @@ void relink_constraints (struct ListBase *list)
ID_NEW(data->tar); ID_NEW(data->tar);
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
data = con->data;
ID_NEW(data->tar);
}
break;
} }
} }
} }
@@ -907,6 +954,14 @@ void copy_constraints (ListBase *dst, ListBase *src)
data = (bFollowPathConstraint*) con->data; data = (bFollowPathConstraint*) con->data;
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
con->data = MEM_dupallocN (con->data);
data = (bStretchToConstraint*) con->data;
}
break;
default: default:
con->data = MEM_dupallocN (con->data); con->data = MEM_dupallocN (con->data);
break; break;
@@ -1427,6 +1482,123 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
} }
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
float scale[3],vec[3],xx[3],zz[3],orth[3];
float totmat[3][3];
float tmat[4][4];
float dist;
data=(bStretchToConstraint*)constraint->data;
if (data->tar){
/* store X orientation before destroying obmat */
xx[0] = ob->obmat[0][0];
xx[1] = ob->obmat[0][1];
xx[2] = ob->obmat[0][2];
Normalise(xx);
/* store Z orientation before destroying obmat */
zz[0] = ob->obmat[2][0];
zz[1] = ob->obmat[2][1];
zz[2] = ob->obmat[2][2];
Normalise(zz);
dist = VecLenf( ob->obmat[3], targetmat[3]);
if (data->orglength == 0) data->orglength = dist;
if (data->bulge ==0) data->bulge = 1.0;
scale[1] = dist/data->orglength;
switch (data->volmode){
/* volume preserving scaling */
case VOLUME_XZ :
scale[0] = 1.0f - (float)sqrt(data->bulge) + (float)sqrt(data->bulge*(data->orglength/dist));
scale[2] = scale[0];
break;
case VOLUME_X:
scale[0] = 1.0f + data->bulge * (data->orglength /dist - 1);
scale[2] = 1.0;
break;
case VOLUME_Z:
scale[0] = 1.0;
scale[2] = 1.0f + data->bulge * (data->orglength /dist - 1);
break;
/* don't care for volume */
case NO_VOLUME:
scale[0] = 1.0;
scale[2] = 1.0;
break;
default: /* should not happen, but in case*/
return;
} /* switch (data->volmode) */
/* Clear the object's rotation and scale */
ob->obmat[0][0]=ob->size[0]*scale[0];
ob->obmat[0][1]=0;
ob->obmat[0][2]=0;
ob->obmat[1][0]=0;
ob->obmat[1][1]=ob->size[1]*scale[1];
ob->obmat[1][2]=0;
ob->obmat[2][0]=0;
ob->obmat[2][1]=0;
ob->obmat[2][2]=ob->size[2]*scale[2];
VecSubf(vec, ob->obmat[3], targetmat[3]);
Normalise(vec);
/* new Y aligns object target connection*/
totmat[1][0] = -vec[0];
totmat[1][1] = -vec[1];
totmat[1][2] = -vec[2];
switch (data->plane){
case PLANE_X:
/* build new Z vector */
/* othogonal to "new Y" "old X! plane */
Crossf(orth, vec, xx);
Normalise(orth);
/* new Z*/
totmat[2][0] = orth[0];
totmat[2][1] = orth[1];
totmat[2][2] = orth[2];
/* we decided to keep X plane*/
Crossf(xx,orth, vec);
Normalise(xx);
totmat[0][0] = xx[0];
totmat[0][1] = xx[1];
totmat[0][2] = xx[2];
break;
case PLANE_Z:
/* build new X vector */
/* othogonal to "new Y" "old Z! plane */
Crossf(orth, vec, zz);
Normalise(orth);
/* new X*/
totmat[0][0] = -orth[0];
totmat[0][1] = -orth[1];
totmat[0][2] = -orth[2];
/* we decided to keep Z */
Crossf(zz,orth, vec);
Normalise(zz);
totmat[2][0] = zz[0];
totmat[2][1] = zz[1];
totmat[2][2] = zz[2];
break;
} /* switch (data->plane) */
Mat4CpyMat4(tmat, ob->obmat);
Mat4MulMat34(ob->obmat, totmat, tmat);
}
}
break;
default: default:
printf ("Error: Unknown constraint type\n"); printf ("Error: Unknown constraint type\n");
break; break;

View File

@@ -1347,6 +1347,14 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar); data->tar = newlibadr(fd, id->lib, data->tar);
}; };
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data;
data= ((bStretchToConstraint*)con->data);
data->tar = newlibadr(fd, id->lib, data->tar);
};
break;
case CONSTRAINT_TYPE_NULL: case CONSTRAINT_TYPE_NULL:
break; break;
} }
@@ -4805,6 +4813,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
expand_doit(fd, mainvar, data->tar); expand_doit(fd, mainvar, data->tar);
break; break;
} }
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = (bStretchToConstraint*)curcon->data;
expand_doit(fd, mainvar, data->tar);
break;
}
case CONSTRAINT_TYPE_NULL: case CONSTRAINT_TYPE_NULL:
break; break;
default: default:

View File

@@ -603,6 +603,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
case CONSTRAINT_TYPE_FOLLOWPATH: case CONSTRAINT_TYPE_FOLLOWPATH:
writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data); writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data);
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
writestruct(wd, DATA, "bStretchToConstraint", 1, con->data);
break;
default: default:
break; break;
} }

View File

@@ -520,7 +520,9 @@ enum {
B_CONSTRAINT_ADD_ACTION, B_CONSTRAINT_ADD_ACTION,
B_CONSTRAINT_ADD_LOCKTRACK, B_CONSTRAINT_ADD_LOCKTRACK,
B_CONSTRAINT_ADD_FOLLOWPATH, B_CONSTRAINT_ADD_FOLLOWPATH,
B_CONSTRAINT_ADD_DISTANCELIMIT B_CONSTRAINT_ADD_DISTANCELIMIT,
B_CONSTRAINT_ADD_STRETCHTO
}; };
/* *********************** */ /* *********************** */

View File

@@ -144,6 +144,15 @@ typedef struct bRotationConstraint{
float zmin, zmax; float zmin, zmax;
} bRotationConstraint; } bRotationConstraint;
/* Stretch to constraint */
typedef struct bStretchToConstraint{
Object *tar;
int volmode;
int plane;
float orglength;
float bulge;
char subtarget[32];
} bStretchToConstraint;
/* bConstraint.type */ /* bConstraint.type */
@@ -185,7 +194,7 @@ typedef struct bRotationConstraint{
#define LOCLIKE_Z 0x00000004 #define LOCLIKE_Z 0x00000004
#define LOCSPACE 0x00000008 #define LOCSPACE 0x00000008
/* Tracking flags */ /* Axis flags */
#define LOCK_X 0x00000000 #define LOCK_X 0x00000000
#define LOCK_Y 0x00000001 #define LOCK_Y 0x00000001
#define LOCK_Z 0x00000002 #define LOCK_Z 0x00000002
@@ -201,37 +210,14 @@ typedef struct bRotationConstraint{
#define TRACK_nY 0x00000004 #define TRACK_nY 0x00000004
#define TRACK_nZ 0x00000005 #define TRACK_nZ 0x00000005
/* Tracking flags */ #define VOLUME_XZ 0x00000000
#define LOCK_X 0x00000000 #define VOLUME_X 0x00000001
#define LOCK_Y 0x00000001 #define VOLUME_Z 0x00000002
#define LOCK_Z 0x00000002 #define NO_VOLUME 0x00000003
#define UP_X 0x00000000 #define PLANE_X 0x00000000
#define UP_Y 0x00000001 #define PLANE_Y 0x00000001
#define UP_Z 0x00000002 #define PLANE_Z 0x00000002
#define TRACK_X 0x00000000
#define TRACK_Y 0x00000001
#define TRACK_Z 0x00000002
#define TRACK_nX 0x00000003
#define TRACK_nY 0x00000004
#define TRACK_nZ 0x00000005
/* Tracking flags */
#define LOCK_X 0x00000000
#define LOCK_Y 0x00000001
#define LOCK_Z 0x00000002
#define UP_X 0x00000000
#define UP_Y 0x00000001
#define UP_Z 0x00000002
#define TRACK_X 0x00000000
#define TRACK_Y 0x00000001
#define TRACK_Z 0x00000002
#define TRACK_nX 0x00000003
#define TRACK_nY 0x00000004
#define TRACK_nZ 0x00000005
#endif #endif

View File

@@ -290,6 +290,9 @@ static void get_constraint_typestring (char *str, bConstraint *con)
case CONSTRAINT_TYPE_FOLLOWPATH: case CONSTRAINT_TYPE_FOLLOWPATH:
strcpy (str, "Follow Path"); strcpy (str, "Follow Path");
return; return;
case CONSTRAINT_TYPE_STRETCHTO:
strcpy (str, "Stretch To");
return;
default: default:
strcpy (str, "Unknown"); strcpy (str, "Unknown");
return; return;
@@ -315,6 +318,8 @@ static int get_constraint_col(bConstraint *con)
return TH_BUT_SETTING; return TH_BUT_SETTING;
case CONSTRAINT_TYPE_FOLLOWPATH: case CONSTRAINT_TYPE_FOLLOWPATH:
return TH_BUT_SETTING2; return TH_BUT_SETTING2;
case CONSTRAINT_TYPE_STRETCHTO:
return TH_BUT_SETTING;
default: default:
return TH_REDALERT; return TH_REDALERT;
} }
@@ -524,7 +529,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
strcpy (data->subtarget, ""); strcpy (data->subtarget, "");
uiBlockEndAlign(block); uiBlockEndAlign(block);
uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001, 1.0, 0.0, 0.0, "Maximum distance to target after solving"); uiDefButF(block, NUM, B_CONSTRAINT_REDRAW, "Tolerance:", *xco+((width/2)-117), *yco-64, 120, 18, &data->tolerance, 0.0001f, 1.0, 0.0, 0.0, "Maximum distance to target after solving");
uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations"); uiDefButI(block, NUM, B_CONSTRAINT_REDRAW, "Iterations:", *xco+((width/2)+3), *yco-64, 120, 18, &data->iterations, 1, 10000, 0.0, 0.0, "Maximum number of solving iterations");
} }
@@ -656,6 +661,54 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiBlockEndAlign(block); uiBlockEndAlign(block);
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = con->data;
bArmature *arm;
height = 105;
BIF_ThemeColor(curCol);
glRects(*xco+3, *yco-height-39, *xco+width+30, *yco-18);
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Target:", *xco+65, *yco-24, 50, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
/* Draw target parameters */
uiBlockBeginAlign(block);
uiDefIDPoinBut(block, test_obpoin_but, B_CONSTRAINT_CHANGETARGET, "OB:", *xco+120, *yco-24, 135, 18, &data->tar, "Target Object");
arm = get_armature(data->tar);
if (arm){
but=uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-42,135,18, &data->subtarget, 0, 24, 0, 0, "Subtarget Bone");
}
else
strcpy (data->subtarget, "");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefButF(block,BUTM,B_CONSTRAINT_REDRAW,"R",*xco, *yco-60,20,18,&(data->orglength),0.0,0,0,0,"Recalculate RLenght");
uiDefButF(block,NUM,B_CONSTRAINT_REDRAW,"Rest Length:",*xco+20, *yco-60,237,18,&(data->orglength),0.0,100,0.5,0.5,"Lenght at Rest Position");
uiBlockEndAlign(block);
uiDefButF(block,NUM,B_CONSTRAINT_REDRAW,"Volume Variation:",*xco+20, *yco-82,237,18,&(data->bulge),0.0,100,0.5,0.5,"Factor between volume variation and stretching");
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, "Vol:",*xco+12, *yco-104,30,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"XZ", *xco+42, *yco-104,30,18, &data->volmode, 12.0, 0.0, 0, 0, "Keep Volume: Scaling X & Z");
uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+72, *yco-104,20,18, &data->volmode, 12.0, 1.0, 0, 0, "Keep Volume: Scaling X");
uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+92, *yco-104,20,18, &data->volmode, 12.0, 2.0, 0, 0, "Keep Volume: Scaling Z");
uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"NONE", *xco+112, *yco-104,50,18, &data->volmode, 12.0, 3.0, 0, 0, "Ignore Volume");
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefBut(block, LABEL, B_CONSTRAINT_TEST,"Plane:",*xco+170, *yco-104,40,18, NULL, 0.0, 0.0, 0.0, 0.0, "");
uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"X", *xco+210, *yco-104,20,18, &data->plane, 12.0, 0.0, 0, 0, "Keep X axis");
uiDefButI(block, ROW,B_CONSTRAINT_REDRAW,"Z", *xco+230, *yco-104,20,18, &data->plane, 12.0, 2.0, 0, 0, "Keep Z axis");
uiBlockEndAlign(block);
}
break;
case CONSTRAINT_TYPE_NULL: case CONSTRAINT_TYPE_NULL:
{ {
height = 17; height = 17;
@@ -711,6 +764,10 @@ static uiBlock *add_constraintmenu(void *arg_unused)
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_LOCKTRACK,"Locked Track", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_FOLLOWPATH,"Follow Path", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_STRETCHTO,"Stretch To", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
if (type==TARGET_BONE) { if (type==TARGET_BONE) {
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -719,9 +776,8 @@ static uiBlock *add_constraintmenu(void *arg_unused)
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_ACTION,"Action", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
} }
uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefBut(block, SEPR, 0, "", 0, yco-=6, 120, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, ""); uiDefBut(block, BUTM, B_CONSTRAINT_ADD_NULL,"Null", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 0, "");
uiTextBoundsBlock(block, 50); uiTextBoundsBlock(block, 50);
@@ -851,6 +907,18 @@ void do_constraintbuts(unsigned short event)
allqueue (REDRAWBUTSOBJECT, 0); allqueue (REDRAWBUTSOBJECT, 0);
} }
break; break;
case B_CONSTRAINT_ADD_STRETCHTO:
{
bConstraint *con;
con = add_new_constraint(CONSTRAINT_TYPE_STRETCHTO);
add_constraint_to_client(con);
test_scene_constraints();
allqueue(REDRAWVIEW3D,0);
allqueue(REDRAWBUTSOBJECT,0);
}
break;
case B_CONSTRAINT_DEL: case B_CONSTRAINT_DEL:
test_scene_constraints(); test_scene_constraints();
allqueue (REDRAWVIEW3D, 0); allqueue (REDRAWVIEW3D, 0);
@@ -1400,7 +1468,7 @@ void object_panel_effects(Object *ob)
uiBlockBeginAlign(block); uiBlockBeginAlign(block);
uiDefButS(block, ROW, B_CALCEFFECT, "RGB", 911,31,45,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed"); uiDefButS(block, ROW, B_CALCEFFECT, "RGB", 911,31,45,20, &paf->texmap, 14.0, 1.0, 0, 0, "Use RGB values as a factor for particle speed");
uiDefButS(block, ROW, B_CALCEFFECT, "Grad", 958,31,44,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed"); uiDefButS(block, ROW, B_CALCEFFECT, "Grad", 958,31,44,20, &paf->texmap, 14.0, 2.0, 0, 0, "Use texture gradient as a factor for particle speed");
uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:", 911,9,91,20, &paf->nabla, 0.0001, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation"); uiDefButF(block, NUM, B_CALCEFFECT, "Nabla:", 911,9,91,20, &paf->nabla, 0.0001f, 1.0, 1, 0, "Specify the dimension of the area for gradient calculation");
} }
} }

View File

@@ -578,6 +578,23 @@ static short detect_constraint_loop (Object *owner, const char* substring, int d
} }
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = curcon->data;
if (!exist_object(data->tar)){
data->tar = NULL;
break;
}
if (detect_constraint_loop (data->tar, data->subtarget, disable, CONSTRAINT_TYPE_LOCKTRACK)){
curcon->flag |= CONSTRAINT_DISABLE;
result = 1;
break;
// return 1;
}
}
break;
case CONSTRAINT_TYPE_FOLLOWPATH: case CONSTRAINT_TYPE_FOLLOWPATH:
{ {
bFollowPathConstraint *data = curcon->data; bFollowPathConstraint *data = curcon->data;
@@ -827,6 +844,12 @@ char *get_con_subtarget_name(bConstraint *constraint, Object *target)
if (data->tar==target) return data->subtarget; if (data->tar==target) return data->subtarget;
} }
break; break;
case CONSTRAINT_TYPE_STRETCHTO:
{
bStretchToConstraint *data = constraint->data;
if (data->tar==target) return data->subtarget;
}
break;
case CONSTRAINT_TYPE_FOLLOWPATH: case CONSTRAINT_TYPE_FOLLOWPATH:
/* wonder if this is relevent, since this constraint /* wonder if this is relevent, since this constraint
* cannot have a subtarget - theeth * cannot have a subtarget - theeth