bugfix [#19525] Curve modifier moves mesh geometry first
authorCampbell Barton <ideasman42@gmail.com>
Fri, 6 Aug 2010 08:27:07 +0000 (08:27 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 6 Aug 2010 08:27:07 +0000 (08:27 +0000)
more of a request then a bug but shows up a strange limitation with curve deform modifier,
The mesh bounding box would set the deform axis start/end to map the deformation of the curve to. This means it ignored offset in the object location and object data location (you could use a dummy vertex to trick it).

Old files wont change, added an option (next to stretch), called 'Bounds Clamp', old files have this behavior but newly made curves have it disabled.
Double checked this gives useful results with stretch on/off and negative axis.

release/scripts/ui/properties_data_curve.py
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/object.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesrna/intern/rna_curve.c

index 32dfc815b6e7529aa6cfff134555dfd1fa73a2b7..f07e29edbb240ddd18f6e3a486143cb01a272bb9 100644 (file)
@@ -193,6 +193,7 @@ class DATA_PT_pathanim(DataButtonsPanelCurve, bpy.types.Panel):
         col = split.column()
         col.prop(curve, "use_path_follow")
         col.prop(curve, "use_stretch")
+        col.prop(curve, "use_deform_bounds")
 
         if wide_ui:
             col = split.column()
index b9f0e6d0551a10906902f9e3ab150528ccbff65a..db6d995aa74a84162863840b01b5bf7f2e51a361 100644 (file)
@@ -40,15 +40,15 @@ struct ListBase;
 struct BezTriple;
 struct BevList;
 
-#define KNOTSU(nu)         ( (nu)->orderu+ (nu)->pntsu+ (((nu)->flagu & CU_NURB_CYCLIC) ? (nu->orderu-1) : 0) )
-#define KNOTSV(nu)         ( (nu)->orderv+ (nu)->pntsv+ (((nu)->flagv & CU_NURB_CYCLIC) ? (nu->orderv-1) : 0) )
+#define KNOTSU(nu)         ( (nu)->orderu+ (nu)->pntsu+ (((nu)->flagu & CU_NURB_CYCLIC) ? ((nu)->orderu-1) : 0) )
+#define KNOTSV(nu)         ( (nu)->orderv+ (nu)->pntsv+ (((nu)->flagv & CU_NURB_CYCLIC) ? ((nu)->orderv-1) : 0) )
 
 /* Non cyclic nurbs have 1 less segment */
 #define SEGMENTSU(nu)      ( ((nu)->flagu & CU_NURB_CYCLIC) ? (nu)->pntsu : (nu)->pntsu-1 )
 #define SEGMENTSV(nu)      ( ((nu)->flagv & CU_NURB_CYCLIC) ? (nu)->pntsv : (nu)->pntsv-1 )
 
 #define CU_DO_TILT(cu, nu) (((nu->flag & CU_2D) && (cu->flag & CU_3D)==0) ? 0 : 1)
-#define CU_DO_RADIUS(cu, nu) ((CU_DO_TILT(cu, nu) || cu->bevobj || cu->ext1!=0.0 || cu->ext2!=0.0) ? 1:0)
+#define CU_DO_RADIUS(cu, nu) ((CU_DO_TILT(cu, nu) || ((cu)->flag & CU_PATH_RADIUS) || (cu)->bevobj || (cu)->ext1!=0.0 || (cu)->ext2!=0.0) ? 1:0)
 
 
 void unlink_curve( struct Curve *cu);
index ce43f0826880e99ed3c1c903e28d39fa395be044..841bd635acf8b73858c56603e5b6477c746fc876 100644 (file)
@@ -127,7 +127,7 @@ Curve *add_curve(char *name, int type)
        cu= alloc_libblock(&G.main->curve, ID_CU, name);
        
        cu->size[0]= cu->size[1]= cu->size[2]= 1.0;
-       cu->flag= CU_FRONT|CU_BACK|CU_PATH_RADIUS;
+       cu->flag= CU_FRONT|CU_BACK|CU_DEFORM_BOUNDS_OFF|CU_PATH_RADIUS;
        cu->pathlen= 100;
        cu->resolu= cu->resolv= 12;
        cu->width= 1.0;
index 7d8c7a08690593dc0ce9359be86537d95f6b0697..1eb7b5d20215d427b3b7be795784316272130aa4 100644 (file)
@@ -713,7 +713,18 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh
        cu->flag |= (CU_PATH|CU_FOLLOW); // needed for path & bevlist
 
        init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0);
-               
+
+       /* dummy bounds, keep if CU_DEFORM_BOUNDS_OFF is set */
+       if(defaxis < 3) {
+               cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
+               cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
+       }
+       else {
+               /* negative, these bounds give a good rest position */
+               cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= -1.0f;
+               cd.dmax[0]= cd.dmax[1]= cd.dmax[2]=  0.0f;
+       }
+       
        /* check whether to use vertex groups (only possible if target is a Mesh)
         * we want either a Mesh with no derived data, or derived data with
         * deformverts
@@ -735,43 +746,77 @@ void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh
                        MDeformVert *dvert = me->dvert;
                        float vec[3];
                        float weight;
+       
 
-                       INIT_MINMAX(cd.dmin, cd.dmax);
-
-                       for(a = 0; a < numVerts; a++, dvert++) {
-                               if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+                       if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
+                               /* dummy bounds */
+                               cd.dmin[0]= cd.dmin[1]= cd.dmin[2]= 0.0f;
+                               cd.dmax[0]= cd.dmax[1]= cd.dmax[2]= 1.0f;
                                
-                               if(defvert_find_weight(dvert, index) > 0.0f) {
-                                       mul_m4_v3(cd.curvespace, vertexCos[a]);
-                                       DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+                               dvert = me->dvert;
+                               for(a = 0; a < numVerts; a++, dvert++) {
+                                       if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+                                       weight= defvert_find_weight(dvert, index);
+       
+                                       if(weight > 0.0f) {
+                                               mul_m4_v3(cd.curvespace, vertexCos[a]);
+                                               copy_v3_v3(vec, vertexCos[a]);
+                                               calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
+                                               interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
+                                               mul_m4_v3(cd.objectspace, vertexCos[a]);
+                                       }
                                }
                        }
-
-                       dvert = me->dvert;
-                       for(a = 0; a < numVerts; a++, dvert++) {
-                               if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
-                               
-                               weight= defvert_find_weight(dvert, index);
-
-                               if(weight > 0.0f) {
-                                       copy_v3_v3(vec, vertexCos[a]);
-                                       calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
-                                       interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
-                                       mul_m4_v3(cd.objectspace, vertexCos[a]);
+                       else {
+                               /* set mesh min/max bounds */
+                               INIT_MINMAX(cd.dmin, cd.dmax);
+       
+                               for(a = 0; a < numVerts; a++, dvert++) {
+                                       if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+                                       
+                                       if(defvert_find_weight(dvert, index) > 0.0f) {
+                                               mul_m4_v3(cd.curvespace, vertexCos[a]);
+                                               DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+                                       }
+                               }
+       
+                               dvert = me->dvert;
+                               for(a = 0; a < numVerts; a++, dvert++) {
+                                       if(dm) dvert = dm->getVertData(dm, a, CD_MDEFORMVERT);
+                                       
+                                       weight= defvert_find_weight(dvert, index);
+       
+                                       if(weight > 0.0f) {
+                                               copy_v3_v3(vec, vertexCos[a]);
+                                               calc_curve_deform(scene, cuOb, vec, defaxis, &cd, NULL);
+                                               interp_v3_v3v3(vertexCos[a], vertexCos[a], vec, weight);
+                                               mul_m4_v3(cd.objectspace, vertexCos[a]);
+                                       }
                                }
                        }
                }
-       } else {
-               INIT_MINMAX(cd.dmin, cd.dmax);
-                       
-               for(a = 0; a < numVerts; a++) {
-                       mul_m4_v3(cd.curvespace, vertexCos[a]);
-                       DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+       }
+       else {
+               if(cu->flag & CU_DEFORM_BOUNDS_OFF) {
+                       for(a = 0; a < numVerts; a++) {
+                               mul_m4_v3(cd.curvespace, vertexCos[a]);
+                               calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
+                               mul_m4_v3(cd.objectspace, vertexCos[a]);
+                       }
                }
-
-               for(a = 0; a < numVerts; a++) {
-                       calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
-                       mul_m4_v3(cd.objectspace, vertexCos[a]);
+               else {
+                       /* set mesh min max bounds */
+                       INIT_MINMAX(cd.dmin, cd.dmax);
+                               
+                       for(a = 0; a < numVerts; a++) {
+                               mul_m4_v3(cd.curvespace, vertexCos[a]);
+                               DO_MINMAX(vertexCos[a], cd.dmin, cd.dmax);
+                       }
+       
+                       for(a = 0; a < numVerts; a++) {
+                               calc_curve_deform(scene, cuOb, vertexCos[a], defaxis, &cd, NULL);
+                               mul_m4_v3(cd.objectspace, vertexCos[a]);
+                       }
                }
        }
        cu->flag = flag;
index 0f540bfa525da8bf5d50ac7269115588ea4c2348..c08a3408505f57b3d06e105aa04805f0573b97d5 100644 (file)
@@ -1627,10 +1627,7 @@ float bsystem_time(struct Scene *scene, Object *ob, float cfra, float ofs)
 void object_scale_to_mat3(Object *ob, float mat[][3])
 {
        float vec[3];
-       
-       vec[0]= ob->size[0]+ob->dsize[0];
-       vec[1]= ob->size[1]+ob->dsize[1];
-       vec[2]= ob->size[2]+ob->dsize[2];
+       add_v3_v3v3(vec, ob->size, ob->dsize);
        size_to_mat3( mat,vec);
 }
 
@@ -1688,7 +1685,7 @@ void object_mat3_to_rot(Object *ob, float mat[][3], int use_compat)
 void object_apply_mat4(Object *ob, float mat[][4])
 {
        float mat3[3][3];
-       VECCOPY(ob->loc, mat[3]);
+       copy_v3_v3(ob->loc, mat[3]);
        mat4_to_size(ob->size, mat);
        copy_m3_m4(mat3, mat);
        object_mat3_to_rot(ob, mat3, 0);
@@ -1796,7 +1793,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
                        copy_m4_m4(mat, rmat);
                }
 
-               VECCOPY(mat[3], vec);
+               copy_v3_v3(mat[3], vec);
                
        }
 }
@@ -1823,7 +1820,7 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
        copy_m4_m4(mat, pchan->pose_mat);
 
        /* but for backwards compatibility, the child has to move to the tail */
-       VECCOPY(vec, mat[1]);
+       copy_v3_v3(vec, mat[1]);
        mul_v3_fl(vec, pchan->bone->length);
        add_v3_v3(mat[3], vec);
 }
index 283c810a1f63eca40fee9d413de7c387031111e3..a013177e1b88759cf0780e0be2b870f420afb2ea 100644 (file)
@@ -245,7 +245,7 @@ typedef struct Curve {
 #define CU_PATH                        8
 #define CU_FOLLOW              16
 #define CU_UV_ORCO             32
-#define CU_DEPRECATED  64
+#define CU_DEFORM_BOUNDS_OFF 64 
 #define CU_STRETCH             128
 #define CU_OFFS_PATHDIST       256
 #define CU_FAST                        512 /* Font: no filling inside editmode */
index eea3c9c76792562b673301456a2d3df28b517768..2cd7953d878752935665bce0752f3da7b895bbd9 100644 (file)
@@ -699,7 +699,12 @@ static void rna_def_path(BlenderRNA *brna, StructRNA *srna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_STRETCH);
        RNA_def_property_ui_text(prop, "Stretch", "Option for curve-deform: makes deformed child to stretch along entire path");
        RNA_def_property_update(prop, 0, "rna_Curve_update_data");
-       
+
+       prop= RNA_def_property(srna, "use_deform_bounds", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", CU_DEFORM_BOUNDS_OFF);
+       RNA_def_property_ui_text(prop, "Bounds Clamp", "Use the mesh bounds to clamp the deformation");
+       RNA_def_property_update(prop, 0, "rna_Curve_update_data");      
+
        prop= RNA_def_property(srna, "use_time_offset", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_OFFS_PATHDIST);
        RNA_def_property_ui_text(prop, "Offset Path Distance", "Children will use TimeOffs value as path distance offset");