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
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2007-11-08 03:06:48 +0300
committerCampbell Barton <ideasman42@gmail.com>2007-11-08 03:06:48 +0300
commit574744bf42aec3f81a3bac6af88e915715bc1975 (patch)
treefa1a8f2da8502cd7a7882def39071a6952dd78f6
parent32758217590e98e810f6d522d4db24c50284bf08 (diff)
New Curve function in the curve specials menu - "Smooth Radius" this smooth's the radius of selected curve points to unselected or endpoints. useful when changing the taper of a long curve
with many points (think treetrunk), it would be nice to take into account distance on the path when doing the curve interpolation. Also moved added undo call's that were missing for 2 of the other curve specials.
-rw-r--r--source/blender/include/BDR_editcurve.h3
-rw-r--r--source/blender/src/editcurve.c213
-rw-r--r--source/blender/src/editobject.c64
3 files changed, 222 insertions, 58 deletions
diff --git a/source/blender/include/BDR_editcurve.h b/source/blender/include/BDR_editcurve.h
index a8c36c3485b..70282aeb0c8 100644
--- a/source/blender/include/BDR_editcurve.h
+++ b/source/blender/include/BDR_editcurve.h
@@ -96,6 +96,9 @@ void add_primitiveNurb(int type);
void clear_tilt(void);
void clever_numbuts_curve(void);
int bezt_compare (const void *e1, const void *e2);
+void setweightNurb( void );
+void setradiusNurb( void );
+void smoothradiusNurb( void );
extern void undo_push_curve(char *name);
diff --git a/source/blender/src/editcurve.c b/source/blender/src/editcurve.c
index a710b53da1c..9d86f88b377 100644
--- a/source/blender/src/editcurve.c
+++ b/source/blender/src/editcurve.c
@@ -1081,6 +1081,219 @@ void switchdirection_knots(float *base, int tot)
MEM_freeN(tempf);
}
+void setweightNurb(void)
+{
+ static float weight= 1.0f;
+ extern ListBase editNurb;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if(nu->bezt) {
+ for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
+ if(bezt->f2 & SELECT)
+ bezt->weight= weight;
+ }
+ }
+ else if(nu->bp) {
+ for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+ if(bp->f1 & SELECT)
+ bp->weight= weight;
+ }
+ }
+ }
+ }
+ BIF_undo_push("Set Curve Weight");
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+}
+
+void setradiusNurb( void )
+{
+ static float radius= 1.0f;
+ extern ListBase editNurb;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ if(fbutton(&radius, 0.0001f, 10.0f, 10, 10, "Set Radius")) {
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if(nu->bezt) {
+ for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
+ if(bezt->f2 & SELECT)
+ bezt->radius= radius;
+ }
+ }
+ else if(nu->bp) {
+ for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
+ if(bp->f1 & SELECT)
+ bp->radius= radius;
+ }
+ }
+ }
+ }
+ BIF_undo_push("Set Curve Radius");
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSALL, 0);
+ allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
+}
+
+
+/* TODO, make smoothing distance based */
+void smoothradiusNurb( void )
+{
+ extern ListBase editNurb;
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ int a;
+
+ /* use for smoothing */
+ int last_sel;
+ int start_sel, end_sel; /* selection indicies, inclusive */
+ float start_rad, end_rad, fac, range;
+
+ for(nu= editNurb.first; nu; nu= nu->next) {
+ if(nu->bezt) {
+
+ for (last_sel=0; last_sel < nu->pntsu; last_sel++) {
+ /* loop over selection segments of a curve, smooth each */
+
+ /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
+ start_sel = end_sel = -1;
+ for(bezt=nu->bezt+last_sel, a=last_sel; a<nu->pntsu; a++, bezt++) {
+ if(bezt->f2 & SELECT) {
+ start_sel = a;
+ break;
+ }
+ }
+ /* incase there are no other selected verts */
+ end_sel = start_sel;
+ for(bezt=nu->bezt+(start_sel+1), a=start_sel+1; a<nu->pntsu; a++, bezt++) {
+ if((bezt->f2 & SELECT)==0) {
+ break;
+ }
+ end_sel = a;
+ }
+
+ if (start_sel == -1) {
+ last_sel = nu->pntsu; /* next... */
+ } else {
+ last_sel = end_sel; /* before we modify it */
+
+ /* now blend between start and end sel */
+ start_rad = end_rad = -1.0;
+
+ if (start_sel == end_sel) {
+ /* simple, only 1 point selected */
+ if (start_sel>0) start_rad = (nu->bezt+start_sel-1)->radius;
+ if (end_sel!=-1 && end_sel < nu->pntsu) end_rad = (nu->bezt+start_sel+1)->radius;
+
+ if (start_rad >= 0.0 && end_rad >= 0.0) (nu->bezt+start_sel)->radius = (start_rad + end_rad)/2;
+ else if (start_rad >= 0.0) (nu->bezt+start_sel)->radius = start_rad;
+ else if (end_rad >= 0.0) (nu->bezt+start_sel)->radius = end_rad;
+ } else {
+ /* if endpoints selected, then use them */
+ if (start_sel==0) {
+ start_rad = (nu->bezt+start_sel)->radius;
+ start_sel++; /* we dont want to edit the selected endpoint */
+ } else {
+ start_rad = (nu->bezt+start_sel-1)->radius;
+ }
+ if (end_sel==nu->pntsu-1) {
+ end_rad = (nu->bezt+end_sel)->radius;
+ end_sel--; /* we dont want to edit the selected endpoint */
+ } else {
+ end_rad = (nu->bezt+end_sel+1)->radius;
+ }
+
+ /* Now Blend between the 2 points */
+ range = (float)(end_sel - start_sel) + 2.0f;
+ for(bezt=nu->bezt+start_sel, a=start_sel; a<=end_sel; a++, bezt++) {
+ fac = (float)(1+a-start_sel) / range;
+ bezt->radius = start_rad*(1.0-fac) + end_rad*fac;
+ }
+ }
+ }
+ }
+ } else if (nu->bp) {
+ /* Same as above, keep these the same! */
+ for (last_sel=0; last_sel < nu->pntsu; last_sel++) {
+ /* loop over selection segments of a curve, smooth each */
+
+ /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */
+ start_sel = end_sel = -1;
+ for(bp=nu->bp+last_sel, a=last_sel; a<nu->pntsu; a++, bp++) {
+ if(bp->f1 & SELECT) {
+ start_sel = a;
+ break;
+ }
+ }
+ /* incase there are no other selected verts */
+ end_sel = start_sel;
+ for(bp=nu->bp+(start_sel+1), a=start_sel+1; a<nu->pntsu; a++, bp++) {
+ if((bp->f1 & SELECT)==0) {
+ break;
+ }
+ end_sel = a;
+ }
+
+ if (start_sel == -1) {
+ last_sel = nu->pntsu; /* next... */
+ } else {
+ last_sel = end_sel; /* before we modify it */
+
+ /* now blend between start and end sel */
+ start_rad = end_rad = -1.0;
+
+ if (start_sel == end_sel) {
+ /* simple, only 1 point selected */
+ if (start_sel>0) start_rad = (nu->bp+start_sel-1)->radius;
+ if (end_sel!=-1 && end_sel < nu->pntsu) end_rad = (nu->bp+start_sel+1)->radius;
+
+ if (start_rad >= 0.0 && end_rad >= 0.0) (nu->bp+start_sel)->radius = (start_rad + end_rad)/2;
+ else if (start_rad >= 0.0) (nu->bp+start_sel)->radius = start_rad;
+ else if (end_rad >= 0.0) (nu->bp+start_sel)->radius = end_rad;
+ } else {
+ /* if endpoints selected, then use them */
+ if (start_sel==0) {
+ start_rad = (nu->bp+start_sel)->radius;
+ start_sel++; /* we dont want to edit the selected endpoint */
+ } else {
+ start_rad = (nu->bp+start_sel-1)->radius;
+ }
+ if (end_sel==nu->pntsu-1) {
+ end_rad = (nu->bp+end_sel)->radius;
+ end_sel--; /* we dont want to edit the selected endpoint */
+ } else {
+ end_rad = (nu->bp+end_sel+1)->radius;
+ }
+
+ /* Now Blend between the 2 points */
+ range = (float)(end_sel - start_sel) + 2.0f;
+ for(bp=nu->bp+start_sel, a=start_sel; a<=end_sel; a++, bp++) {
+ fac = (float)(1+a-start_sel) / range;
+ bp->radius = start_rad*(1.0-fac) + end_rad*fac;
+ }
+ }
+ }
+ }
+ }
+ }
+ BIF_undo_push("Smooth Curve Radius");
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSALL, 0);
+ allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
+}
+
+
+
/* **************** EDIT ************************ */
/* next == 1 -> select next */
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index 997593b30b1..3e316d578ab 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -2476,7 +2476,7 @@ void special_editmenu(void)
}
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
- nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4");
+ nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight %x3|Set Radius %x4|Smooth Radius %x5");
switch(nr) {
case 1:
@@ -2486,67 +2486,15 @@ void special_editmenu(void)
switchdirectionNurb2();
break;
case 3:
- {
- static float weight= 1.0f;
- extern ListBase editNurb;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
- for(nu= editNurb.first; nu; nu= nu->next) {
- if(nu->bezt) {
- for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
- if(bezt->f2 & SELECT)
- bezt->weight= weight;
- }
- }
- else if(nu->bp) {
- for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
- if(bp->f1 & SELECT)
- bp->weight= weight;
- }
- }
- }
- }
- }
+ setweightNurb();
break;
case 4:
- {
- static float radius= 1.0f;
- extern ListBase editNurb;
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- int a;
-
- if(fbutton(&radius, 0.0001f, 10.0f, 10, 10, "Set Radius")) {
- for(nu= editNurb.first; nu; nu= nu->next) {
- if(nu->bezt) {
- for(bezt=nu->bezt, a=0; a<nu->pntsu; a++, bezt++) {
- if(bezt->f2 & SELECT)
- bezt->radius= radius;
- }
- }
- else if(nu->bp) {
- for(bp=nu->bp, a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
- if(bp->f1 & SELECT)
- bp->radius= radius;
- }
- }
- }
- }
-
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSALL, 0);
- allqueue(REDRAWINFO, 1); /* 1, because header->win==0! */
-
- }
+ setradiusNurb();
+ break;
+ case 5:
+ smoothradiusNurb();
break;
}
-
DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
}
else if(G.obedit->type==OB_ARMATURE) {