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
path: root/source
diff options
context:
space:
mode:
authorMartin Poirier <theeth@yahoo.com>2004-09-06 00:21:16 +0400
committerMartin Poirier <theeth@yahoo.com>2004-09-06 00:21:16 +0400
commitae9347662b4d7baf9ad2d5cbdb89c923d463db60 (patch)
treee1f9b702a553294951814da78cf013159215b4c8 /source
parent81e960d1c47ccd8701c218b303013cf52e513a5b (diff)
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).
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/constraint.c196
-rw-r--r--source/blender/blenloader/intern/readfile.c14
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/include/butspace.h4
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h48
-rw-r--r--source/blender/src/buttons_object.c76
-rw-r--r--source/blender/src/editconstraint.c23
7 files changed, 316 insertions, 48 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index e590dd1dc24..221847de6bf 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -122,6 +122,12 @@ char constraint_has_target (bConstraint *con) {
if (data->tar)
return 1;
}
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data = con->data;
+ if (data->tar)
+ return 1;
+ }
break;
}
// 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)
{
- /*
- * If the target for this constraint is target, return a pointer
- * to the name for this constraints subtarget ... NULL otherwise
- */
+/*
+* If the target for this constraint is target, return a pointer
+* to the name for this constraints subtarget ... NULL otherwise
+ */
switch (con->type) {
-
- case CONSTRAINT_TYPE_ACTION:
+ case CONSTRAINT_TYPE_ACTION:
{
bActionConstraint *data = con->data;
return data->tar;
}
break;
- case CONSTRAINT_TYPE_LOCLIKE:
+ case CONSTRAINT_TYPE_LOCLIKE:
{
bLocateLikeConstraint *data = con->data;
return data->tar;
}
break;
- case CONSTRAINT_TYPE_ROTLIKE:
+ case CONSTRAINT_TYPE_ROTLIKE:
{
bRotateLikeConstraint *data = con->data;
return data->tar;
}
break;
- case CONSTRAINT_TYPE_KINEMATIC:
+ case CONSTRAINT_TYPE_KINEMATIC:
{
bKinematicConstraint *data = con->data;
return data->tar;
}
break;
- case CONSTRAINT_TYPE_TRACKTO:
+ case CONSTRAINT_TYPE_TRACKTO:
{
bTrackToConstraint *data = con->data;
return data->tar;
}
break;
- case CONSTRAINT_TYPE_LOCKTRACK:
+ case CONSTRAINT_TYPE_LOCKTRACK:
{
bLockTrackConstraint *data = con->data;
return data->tar;
}
break;
- case CONSTRAINT_TYPE_FOLLOWPATH:
+ case CONSTRAINT_TYPE_FOLLOWPATH:
{
bFollowPathConstraint *data = con->data;
return data->tar;
}
break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data = con->data;
+ return (data->tar);
+ }
+ break;
}
return NULL;
@@ -310,6 +321,18 @@ void *new_constraint_data (short type)
result = data;
}
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:
result = NULL;
break;
@@ -722,6 +745,21 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
Mat4One (mat);
}
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:
Mat4One(mat);
break;
@@ -796,6 +834,15 @@ void relink_constraints (struct ListBase *list)
ID_NEW(data->tar);
}
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;
}
break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data;
+
+ con->data = MEM_dupallocN (con->data);
+ data = (bStretchToConstraint*) con->data;
+ }
+ break;
default:
con->data = MEM_dupallocN (con->data);
break;
@@ -1427,6 +1482,123 @@ void evaluate_constraint (bConstraint *constraint, Object *ob, short ownertype,
}
}
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:
printf ("Error: Unknown constraint type\n");
break;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 498b84abb2c..1e9b7aa8e99 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1347,6 +1347,14 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
data->tar = newlibadr(fd, id->lib, data->tar);
};
break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data;
+ data= ((bStretchToConstraint*)con->data);
+ data->tar = newlibadr(fd, id->lib, data->tar);
+ };
+ break;
+
case CONSTRAINT_TYPE_NULL:
break;
}
@@ -4805,6 +4813,12 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
expand_doit(fd, mainvar, data->tar);
break;
}
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data = (bStretchToConstraint*)curcon->data;
+ expand_doit(fd, mainvar, data->tar);
+ break;
+ }
case CONSTRAINT_TYPE_NULL:
break;
default:
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 6d84c120422..159b1e7a11f 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -603,6 +603,9 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
case CONSTRAINT_TYPE_FOLLOWPATH:
writestruct(wd, DATA, "bFollowPathConstraint", 1, con->data);
break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ writestruct(wd, DATA, "bStretchToConstraint", 1, con->data);
+ break;
default:
break;
}
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 878f9491052..54af18adfb3 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -520,7 +520,9 @@ enum {
B_CONSTRAINT_ADD_ACTION,
B_CONSTRAINT_ADD_LOCKTRACK,
B_CONSTRAINT_ADD_FOLLOWPATH,
- B_CONSTRAINT_ADD_DISTANCELIMIT
+ B_CONSTRAINT_ADD_DISTANCELIMIT,
+ B_CONSTRAINT_ADD_STRETCHTO
+
};
/* *********************** */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index b4b380a6a2e..06a7844b785 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -144,6 +144,15 @@ typedef struct bRotationConstraint{
float zmin, zmax;
} bRotationConstraint;
+/* Stretch to constraint */
+typedef struct bStretchToConstraint{
+ Object *tar;
+ int volmode;
+ int plane;
+ float orglength;
+ float bulge;
+ char subtarget[32];
+} bStretchToConstraint;
/* bConstraint.type */
@@ -185,23 +194,7 @@ typedef struct bRotationConstraint{
#define LOCLIKE_Z 0x00000004
#define LOCSPACE 0x00000008
-/* 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
-
-/* Tracking flags */
+/* Axis flags */
#define LOCK_X 0x00000000
#define LOCK_Y 0x00000001
#define LOCK_Z 0x00000002
@@ -217,21 +210,14 @@ typedef struct bRotationConstraint{
#define TRACK_nY 0x00000004
#define TRACK_nZ 0x00000005
-/* Tracking flags */
-#define LOCK_X 0x00000000
-#define LOCK_Y 0x00000001
-#define LOCK_Z 0x00000002
+#define VOLUME_XZ 0x00000000
+#define VOLUME_X 0x00000001
+#define VOLUME_Z 0x00000002
+#define NO_VOLUME 0x00000003
-#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
+#define PLANE_X 0x00000000
+#define PLANE_Y 0x00000001
+#define PLANE_Z 0x00000002
#endif
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index 0708fea0b13..ecb23733523 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -290,6 +290,9 @@ static void get_constraint_typestring (char *str, bConstraint *con)
case CONSTRAINT_TYPE_FOLLOWPATH:
strcpy (str, "Follow Path");
return;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ strcpy (str, "Stretch To");
+ return;
default:
strcpy (str, "Unknown");
return;
@@ -315,6 +318,8 @@ static int get_constraint_col(bConstraint *con)
return TH_BUT_SETTING;
case CONSTRAINT_TYPE_FOLLOWPATH:
return TH_BUT_SETTING2;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ return TH_BUT_SETTING;
default:
return TH_REDALERT;
}
@@ -524,7 +529,7 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
strcpy (data->subtarget, "");
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");
}
@@ -656,6 +661,54 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiBlockEndAlign(block);
}
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:
{
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_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) {
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, 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, "");
uiTextBoundsBlock(block, 50);
@@ -851,6 +907,18 @@ void do_constraintbuts(unsigned short event)
allqueue (REDRAWBUTSOBJECT, 0);
}
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:
test_scene_constraints();
allqueue (REDRAWVIEW3D, 0);
@@ -1400,7 +1468,7 @@ void object_panel_effects(Object *ob)
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, "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");
}
}
diff --git a/source/blender/src/editconstraint.c b/source/blender/src/editconstraint.c
index c06a11a6b7d..6123da0062b 100644
--- a/source/blender/src/editconstraint.c
+++ b/source/blender/src/editconstraint.c
@@ -578,6 +578,23 @@ static short detect_constraint_loop (Object *owner, const char* substring, int d
}
}
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:
{
bFollowPathConstraint *data = curcon->data;
@@ -827,6 +844,12 @@ char *get_con_subtarget_name(bConstraint *constraint, Object *target)
if (data->tar==target) return data->subtarget;
}
break;
+ case CONSTRAINT_TYPE_STRETCHTO:
+ {
+ bStretchToConstraint *data = constraint->data;
+ if (data->tar==target) return data->subtarget;
+ }
+ break;
case CONSTRAINT_TYPE_FOLLOWPATH:
/* wonder if this is relevent, since this constraint
* cannot have a subtarget - theeth