Added Map Taper option which if enabled maps affect of taper object on

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
This commit is contained in:
Sergey Sharybin
2012-11-08 08:16:44 +00:00
parent 09cce17d84
commit 529209ff83
4 changed files with 87 additions and 39 deletions

View 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"

View 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);
data[0] = bevp->vec[0] + fac * vec[0];
data[1] = bevp->vec[1] + fac * vec[1];
data[2] = bevp->vec[2] + fac * vec[2];
if (nbevp == NULL) {
copy_v3_v3(data, bevp->vec);
copy_qt_qt(quat, bevp->quat);
}
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];
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] += fac * vec[0];
data[1] += fac * vec[1];
data[2] += fac * vec[2];
}
else {
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)

View 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

View 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);