[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12519] trunk/blender/source/blender: New Curve function in the curve specials menu - "Smooth Radius" this smooth' s the radius of selected curve points to unselected or endpoints.

Campbell Barton cbarton at metavr.com
Thu Nov 8 01:06:48 CET 2007


Revision: 12519
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12519
Author:   campbellbarton
Date:     2007-11-08 01:06:48 +0100 (Thu, 08 Nov 2007)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BDR_editcurve.h
    trunk/blender/source/blender/src/editcurve.c
    trunk/blender/source/blender/src/editobject.c

Modified: trunk/blender/source/blender/include/BDR_editcurve.h
===================================================================
--- trunk/blender/source/blender/include/BDR_editcurve.h	2007-11-07 22:55:01 UTC (rev 12518)
+++ trunk/blender/source/blender/include/BDR_editcurve.h	2007-11-08 00:06:48 UTC (rev 12519)
@@ -96,6 +96,9 @@
 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);
 

Modified: trunk/blender/source/blender/src/editcurve.c
===================================================================
--- trunk/blender/source/blender/src/editcurve.c	2007-11-07 22:55:01 UTC (rev 12518)
+++ trunk/blender/source/blender/src/editcurve.c	2007-11-08 00:06:48 UTC (rev 12519)
@@ -1081,6 +1081,219 @@
 	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 		*/

Modified: trunk/blender/source/blender/src/editobject.c
===================================================================
--- trunk/blender/source/blender/src/editobject.c	2007-11-07 22:55:01 UTC (rev 12518)
+++ trunk/blender/source/blender/src/editobject.c	2007-11-08 00:06:48 UTC (rev 12519)
@@ -2476,7 +2476,7 @@
 	}
 	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 @@
 			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) {





More information about the Bf-blender-cvs mailing list