Added Map Taper option which if enabled maps affect of taper object on
authorSergey Sharybin <sergey.vfx@gmail.com>
Thu, 8 Nov 2012 08:16:44 +0000 (08:16 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Thu, 8 Nov 2012 08:16:44 +0000 (08:16 +0000)
actually beveled part of curve (previously affect of taper would have
been clamped by start/end bevel factor)

Here's an illustration:
http://wiki.blender.org/uploads/5/5d/Blender2.65_CurveMapTaper.png

release/scripts/startup/bl_ui/properties_data_curve.py
source/blender/blenkernel/intern/displist.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesrna/intern/rna_curve.c

index a8f4aa30e95efc30ab63068294aeb4636ed98218..7747ef45c4df55226415eb759c4c0ff39e5adfb2 100644 (file)
@@ -174,11 +174,14 @@ class DATA_PT_geometry_curve(CurveButtonsPanel, Panel):
         col.prop(curve, "bevel_object", text="")
 
         col = layout.column(align=True)
-        col.active = (curve.bevel_object is not None)
-        col.prop(curve, "use_fill_caps")
         col.prop(curve, "bevel_factor_start")
         col.prop(curve, "bevel_factor_end")
 
+        row = col.row()
+        row.active = (curve.bevel_object is not None)
+        row.prop(curve, "use_fill_caps")
+        row.prop(curve, "use_map_taper")
+
 
 class DATA_PT_pathanim(CurveButtonsPanelCurve, Panel):
     bl_label = "Path Animation"
index e13d05d0a2fd22737ca56f80c23f5a3c90cbecf7..a78a9af54ae3c78c60cbdd5fa992ada29189e767 100644 (file)
@@ -630,7 +630,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dis
  * - first point left, last point right
  * - based on subdivided points in original curve, not on points in taper curve (still)
  */
-float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
+static float displist_calc_taper(Scene *scene, Object *taperobj, float fac)
 {
        DispList *dl;
 
@@ -643,7 +643,6 @@ float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
                dl = taperobj->disp.first;
        }
        if (dl) {
-               float fac = ((float)cur) / (float)(tot - 1);
                float minx, dx, *fp;
                int a;
 
@@ -671,6 +670,13 @@ float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
        return 1.0;
 }
 
+float BKE_displist_calc_taper(Scene *scene, Object *taperobj, int cur, int tot)
+{
+       float fac = ((float)cur) / (float)(tot - 1);
+
+       return displist_calc_taper(scene, taperobj, fac);
+}
+
 void BKE_displist_make_mball(Scene *scene, Object *ob)
 {
        if (!ob || ob->type != OB_MBALL)
@@ -1240,7 +1246,7 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase,
        }
 }
 
-static void rotateBevelPiece(Curve *cu, BevPoint *bevp, DispList *dlb, float widfac, float fac, float **data_r)
+static void rotateBevelPiece(Curve *cu, BevPoint *bevp, BevPoint *nbevp, DispList *dlb, float bev_blend, float widfac, float fac, float **data_r)
 {
        float *fp, *data = *data_r;
        int b;
@@ -1248,22 +1254,48 @@ static void rotateBevelPiece(Curve *cu, BevPoint *bevp, DispList *dlb, float wid
        fp = dlb->verts;
        for (b = 0; b < dlb->nr; b++, fp += 3, data += 3) {
                if (cu->flag & CU_3D) {
-                       float vec[3];
+                       float vec[3], quat[4];
 
                        vec[0] = fp[1] + widfac;
                        vec[1] = fp[2];
                        vec[2] = 0.0;
 
-                       mul_qt_v3(bevp->quat, vec);
+                       if (nbevp == NULL) {
+                               copy_v3_v3(data, bevp->vec);
+                               copy_qt_qt(quat, bevp->quat);
+                       }
+                       else {
+                               interp_v3_v3v3(data, bevp->vec, nbevp->vec, bev_blend);
+                               interp_qt_qtqt(quat, bevp->quat, nbevp->quat, bev_blend);
+                       }
+
+                       mul_qt_v3(quat, vec);
 
-                       data[0] = bevp->vec[0] + fac * vec[0];
-                       data[1] = bevp->vec[1] + fac * vec[1];
-                       data[2] = bevp->vec[2] + fac * vec[2];
+                       data[0] += fac * vec[0];
+                       data[1] += fac * vec[1];
+                       data[2] += fac * vec[2];
                }
                else {
-                       data[0] = bevp->vec[0] + fac * (widfac + fp[1]) * bevp->sina;
-                       data[1] = bevp->vec[1] + fac * (widfac + fp[1]) * bevp->cosa;
-                       data[2] = bevp->vec[2] + fac * fp[2];
+                       float sina, cosa;
+
+                       if (nbevp == NULL) {
+                               copy_v3_v3(data, bevp->vec);
+                               sina = bevp->sina;
+                               cosa = bevp->cosa;
+                       }
+                       else {
+                               interp_v3_v3v3(data, bevp->vec, nbevp->vec, bev_blend);
+
+                               /* perhaps we need to interpolate angles instead. but the thing is
+                                * cosa and sina are not actually sine and cosine
+                                */
+                               sina = nbevp->sina * bev_blend + bevp->sina * (1.0f - bev_blend);
+                               cosa = nbevp->cosa * bev_blend + bevp->cosa * (1.0f - bev_blend);
+                       }
+
+                       data[0] += fac * (widfac + fp[1]) * sina;
+                       data[1] += fac * (widfac + fp[1]) * cosa;
+                       data[2] += fac * fp[2];
                }
        }
 
@@ -1399,8 +1431,8 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
                                                        firstblend = 1.0f - (bevfac1 * (bl->nr - 1) - (int)(bevfac1 * (bl->nr - 1)));
                                                        lastblend  =         bevfac2 * (bl->nr - 1) - (int)(bevfac2 * (bl->nr - 1));
 
-                                                       if (steps > bl->nr) {
-                                                               steps = bl->nr;
+                                                       if (start + steps > bl->nr) {
+                                                               steps = bl->nr - start;
                                                                lastblend = 1.0f;
                                                        }
 
@@ -1438,7 +1470,29 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
                                                                                fac = bevp->radius;
                                                                }
                                                                else {
-                                                                       fac = BKE_displist_calc_taper(scene, cu->taperobj, i, bl->nr);
+                                                                       float len, taper_fac;
+
+                                                                       if (cu->flag & CU_MAP_TAPER) {
+                                                                               len = (steps - 3) + firstblend + lastblend;
+
+                                                                               if (a == 0)
+                                                                                       taper_fac = 0.0f;
+                                                                               else if (a == steps - 1)
+                                                                                       taper_fac = 1.0f;
+                                                                               else
+                                                                                       taper_fac = ((float) a - (1.0f - firstblend)) / len;
+                                                                       }
+                                                                       else {
+                                                                               len = bl->nr - 1;
+                                                                               taper_fac = (float) i / len;
+
+                                                                               if (a == 0)
+                                                                                       taper_fac += (1.0f - firstblend) / len;
+                                                                               else if (a == steps - 1)
+                                                                                       taper_fac -= (1.0f - lastblend) / len;
+                                                                       }
+
+                                                                       fac = displist_calc_taper(scene, cu->taperobj, taper_fac);
                                                                }
 
                                                                if (bevp->split_tag) {
@@ -1446,27 +1500,12 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba
                                                                }
 
                                                                /* rotate bevel piece and write in data */
-                                                               rotateBevelPiece(cu, bevp, dlb, widfac, fac, &data);
-
-                                                               if (a == 1 || a == steps - 1) {
-                                                                       float *cur_fp = cur_data, *prev_fp = cur_data - 3 * dlb->nr;
-                                                                       int b;
-
-                                                                       for (b = 0; b < dlb->nr; b++, prev_fp += 3, cur_fp += 3) {
-                                                                               float cur[3], prev[3];
-
-                                                                               copy_v3_v3(cur, cur_fp);
-                                                                               copy_v3_v3(prev, prev_fp);
-
-                                                                               if (a == 1)
-                                                                                       interp_v3_v3v3(prev, cur_fp, prev_fp, firstblend);
-                                                                               if (a == steps - 1)
-                                                                                       interp_v3_v3v3(cur, prev_fp, cur_fp, lastblend);
-
-                                                                               copy_v3_v3(cur_fp, cur);
-                                                                               copy_v3_v3(prev_fp, prev);
-                                                                       }
-                                                               }
+                                                               if (a == 0)
+                                                                       rotateBevelPiece(cu, bevp, bevp + 1, dlb, 1.0f - firstblend, widfac, fac, &data);
+                                                               else if (a == steps - 1)
+                                                                       rotateBevelPiece(cu, bevp, bevp - 1, dlb, 1.0f - lastblend, widfac, fac, &data);
+                                                               else
+                                                                       rotateBevelPiece(cu, bevp, NULL, dlb, 0.0f, widfac, fac, &data);
 
                                                                if (cu->bevobj && (cu->flag & CU_FILL_CAPS)) {
                                                                        if (a == 1)
index 3cf84648ea6b02b9db1e67196f191fa37b1c64f6..deb9902c35d073c694419ffe0bfac564b5fdbd51 100644 (file)
@@ -201,8 +201,8 @@ typedef struct Curve {
        float twist_smooth, smallcaps_scale;
 
        int pathlen;
-       short pad, totcol;
-       short flag, bevresol;
+       short bevresol, totcol;
+       int flag;
        float width, ext1, ext2;
        
        /* default */
@@ -269,6 +269,7 @@ typedef struct Curve {
 #define CU_PATH_RADIUS 4096 /* make use of the path radius if this is enabled (default for new curves) */
 #define CU_DEFORM_FILL 8192 /* fill 2d curve after deformation */
 #define CU_FILL_CAPS   16384 /* fill bevel caps */
+#define CU_MAP_TAPER   32768 /* map taper object to bevelled area */
 
 /* twist mode */
 #define CU_TWIST_Z_UP                  0
index a3cff99ddc89acce035075d79c10895d090461de..1e1a8c82b8eb0459e7847e0f7e275201ca61e9eb 100644 (file)
@@ -1422,6 +1422,11 @@ static void rna_def_curve(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Fill Caps", "Fill caps for beveled curves");
        RNA_def_property_update(prop, 0, "rna_Curve_update_data");
 
+       prop = RNA_def_property(srna, "use_map_taper", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_MAP_TAPER);
+       RNA_def_property_ui_text(prop, "Map Taper", "Map effect of taper object on actually bevelled curve");
+       RNA_def_property_update(prop, 0, "rna_Curve_update_data");
+
        /* texture space */
        prop = RNA_def_property(srna, "use_auto_texspace", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "texflag", CU_AUTOSPACE);