Feature for Curve objects in Blender; 'tapering'.

Next to the "BevOb" button you now have a "TaperOb" button to give a name
of a curve object which defines the width of extrusion of the 'BevObj'
along the curve. The TaperOb curve typically is horizontal, where the
height denotes the width.
Important rules;
- Only the firste curve in TaperObj is evaluated
- the first width is left, last width is right
- it scales the width of normal extrusions based on evaluating the taper
  curve; which means sharp corners in taper curve won't be easily visible

(That latter feature could be improved by extrusing based on the points
in the taper curve; this is a *lot* more work)
This commit is contained in:
Ton Roosendaal
2004-08-29 09:21:52 +00:00
parent 19ba12946c
commit 4edfc3a919
6 changed files with 86 additions and 21 deletions

View File

@@ -1666,6 +1666,54 @@ void set_displist_onlyzero(int val)
dl_onlyzero= val;
}
/* taper rules:
- only 1 curve
- first point left, last point right
- based on subdivided points in original curve, not on points in taper curve (still)
*/
static float calc_taper(Object *taperobj, int cur, int tot)
{
Curve *cu;
DispList *dl;
if(taperobj==NULL) return 1.0;
cu= taperobj->data;
dl= cu->disp.first;
if(dl==NULL) {
makeDispList(taperobj);
dl= cu->disp.first;
}
if(dl) {
float fac= ((float)cur)/(float)(tot-1);
float minx, dx, *fp;
int a;
/* horizontal size */
minx= dl->verts[0];
dx= dl->verts[3*(dl->nr-1)] - minx;
if(dx>0.0) {
fp= dl->verts;
for(a=0; a<dl->nr; a++, fp+=3) {
if( (fp[0]-minx)/dx >= fac) {
/* interpolate with prev */
if(a>0) {
float fac1= (fp[-3]-minx)/dx;
float fac2= (fp[0]-minx)/dx;
if(fac1!=fac2)
return fp[1]*(fac1-fac)/(fac1-fac2) + fp[-2]*(fac-fac2)/(fac1-fac2);
}
return fp[1];
}
}
return fp[-2]; // last y coord
}
}
return 1.0;
}
void makeDispList(Object *ob)
{
EditMesh *em = G.editMesh;
@@ -1888,14 +1936,18 @@ void makeDispList(Object *ob)
data= dl->verts;
bevp= (BevPoint *)(bl+1);
a= bl->nr;
while(a--) { /* for each point of poly make a bevel piece */
for(a=0; a<bl->nr; a++) { /* for each point of poly make a bevel piece */
float fac;
/* returns 1.0 if no taper, of course */
fac= calc_taper(cu->taperobj, a, bl->nr);
/* rotate bevel piece and write in data */
fp1= dlb->verts;
b= dlb->nr;
while(b--) {
if(cu->flag & CU_3D) {
vec[0]= fp1[1]+widfac;
@@ -1904,14 +1956,14 @@ void makeDispList(Object *ob)
Mat3MulVecfl(bevp->mat, vec);
data[0]= bevp->x+ vec[0];
data[1]= bevp->y+ vec[1];
data[2]= bevp->z+ vec[2];
data[0]= bevp->x+ fac*vec[0];
data[1]= bevp->y+ fac*vec[1];
data[2]= bevp->z+ fac*vec[2];
}
else {
data[0]= bevp->x+ (fp1[1]+widfac)*bevp->sina;
data[1]= bevp->y+ (fp1[1]+widfac)*bevp->cosa;
data[2]= bevp->z+ fp1[2];
data[0]= bevp->x+ fac*(fp1[1]+widfac)*bevp->sina;
data[1]= bevp->y+ fac*(fp1[1]+widfac)*bevp->cosa;
data[2]= bevp->z+ fac*fp1[2];
}
data+=3;

View File

@@ -218,28 +218,29 @@ void unlink_object(Object *ob)
/* check all objects: parents en bevels */
obt= G.main->object.first;
while(obt) {
if(obt->id.lib==0) {
if(obt->id.lib==NULL) {
if(obt->parent==ob) {
obt->parent= 0;
obt->parent= NULL;
if(ob->type==OB_LATTICE) freedisplist(&obt->disp);
}
if(obt->track==ob) obt->track= 0;
if(obt->track==ob) obt->track= NULL;
if ELEM(obt->type, OB_CURVE, OB_FONT) {
cu= obt->data;
if(cu->bevobj==ob) cu->bevobj= 0;
if(cu->textoncurve==ob) cu->textoncurve= 0;
if(cu->bevobj==ob) cu->bevobj= NULL;
if(cu->taperobj==ob) cu->taperobj= NULL;
if(cu->textoncurve==ob) cu->textoncurve= NULL;
}
if(obt->type==OB_IKA) {
Ika *ika= obt->data;
Deform *def= ika->def;
if(ika->parent==ob) ika->parent= 0;
if(ika->parent==ob) ika->parent= NULL;
a= ika->totdef;
while(a--) {
if(def->ob==ob) {
ika->totdef= 0;
MEM_freeN(ika->def);
ika->def= 0;
ika->def= NULL;
break;
}
def++;

View File

@@ -1781,6 +1781,7 @@ static void lib_link_curve(FileData *fd, Main *main)
for(a=0; a<cu->totcol; a++) cu->mat[a]= newlibadr_us(fd, cu->id.lib, cu->mat[a]);
cu->bevobj= newlibadr(fd, cu->id.lib, cu->bevobj);
cu->taperobj= newlibadr(fd, cu->id.lib, cu->taperobj);
cu->textoncurve= newlibadr(fd, cu->id.lib, cu->textoncurve);
cu->vfont= newlibadr_us(fd, cu->id.lib, cu->vfont);
@@ -4535,6 +4536,7 @@ static void expand_curve(FileData *fd, Main *mainvar, Curve *cu)
expand_doit(fd, mainvar, cu->key);
expand_doit(fd, mainvar, cu->ipo);
expand_doit(fd, mainvar, cu->bevobj);
expand_doit(fd, mainvar, cu->taperobj);
expand_doit(fd, mainvar, cu->textoncurve);
}

View File

@@ -110,7 +110,7 @@ typedef struct Curve {
ListBase nurb;
ListBase disp;
struct Object *bevobj, *textoncurve;
struct Object *bevobj, *taperobj, *textoncurve;
struct Ipo *ipo;
Path *path;
struct Key *key;

View File

@@ -1270,7 +1270,8 @@ static void editing_panel_curve_type(Object *ob, Curve *cu)
uiDefButF(block, NUM, B_MAKEDISP, "Ext1:", 760,70,150,19, &cu->ext1, 0.0, 5.0, 10, 0, "");
uiDefButF(block, NUM, B_MAKEDISP, "Ext2:", 760,50,150,19, &cu->ext2, 0.0, 2.0, 1, 0, "");
uiDefButS(block, NUM, B_MAKEDISP, "BevResol:", 760,30,150,19, &cu->bevresol, 0.0, 10.0, 0, 0, "");
uiDefIDPoinBut(block, test_obcurpoin_but, B_MAKEDISP, "BevOb:", 760,10,150,19, &cu->bevobj, "");
uiDefIDPoinBut(block, test_obcurpoin_but, B_MAKEDISP, "BevOb:", 760,10,150,19, &cu->bevobj, "Curve object name that defines the bevel shape");
uiDefIDPoinBut(block, test_obcurpoin_but, B_MAKEDISP, "TaperOb:", 760,-10,150,19, &cu->taperobj, "Curve object name that defines the taper (width)");
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);

View File

@@ -1175,7 +1175,7 @@ void exit_editmode(int freedata) /* freedata==0 at render */
text_to_curve(base->object, 0);
makeDispList(base->object);
}
if(cu->bevobj== ob) {
if(cu->bevobj==ob || cu->taperobj==ob) {
makeDispList(base->object);
}
}
@@ -2142,6 +2142,7 @@ void copy_attr(short event)
cu1= base->object->data;
cu1->bevobj= cu->bevobj;
cu1->taperobj= cu->taperobj;
cu1->width= cu->width;
cu1->bevresol= cu->bevresol;
cu1->ext1= cu->ext1;
@@ -3931,6 +3932,7 @@ void special_aftertrans_update(char mode, int flip, short canceled, int keyflags
cu= ob->data;
if(cu->bevobj && (cu->bevobj->flag & SELECT) ) doit= 1;
else if(cu->taperobj && (cu->taperobj->flag & SELECT) ) doit= 1;
else if(cu->textoncurve) {
if(cu->textoncurve->flag & SELECT) doit= 1;
else if(ob->flag & SELECT) doit= 1;
@@ -3947,6 +3949,8 @@ void special_aftertrans_update(char mode, int flip, short canceled, int keyflags
if(cu->bevobj && (cu->bevobj->flag & SELECT) )
makeDispList(ob);
else if(cu->taperobj && (cu->taperobj->flag & SELECT) )
makeDispList(ob);
}
where_is_object(ob); /* always do, for track etc. */
@@ -4561,8 +4565,8 @@ void transform(int mode)
if(mode=='w' && G.obedit==0) return;
if (G.obedit && G.obedit->type == OB_MESH) {
undo_push_mesh(transform_mode_to_string(mode));
}
undo_push_mesh(transform_mode_to_string(mode));
}
/* what data will be involved? */
if(G.obedit) {
@@ -6142,6 +6146,10 @@ void transform(int mode)
if(edge_creases) MEM_freeN(edge_creases);
tottrans= 0;
/* undo after transform, since it's storing current situations */
//if(canceled==0 && G.obedit==NULL)
// BIF_write_undo(transform_mode_to_string(mode));
}
void std_rmouse_transform(void (*xf_func)(int))
@@ -6300,6 +6308,7 @@ void single_obdata_users(int flag)
case OB_FONT:
ob->data= cu= copy_curve(ob->data);
ID_NEW(cu->bevobj);
ID_NEW(cu->taperobj);
makeDispList(ob);
break;
case OB_LATTICE: