[Bf-committers] patch - bf-blender Sel Same ___

Campbell Barton bf-committers@blender.org
Sun, 18 Jul 2004 15:40:02 +1000


This is a multi-part message in MIME format.
--------------000904040801050002070706
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi, I have braught this in from tuhopuu2
Here are the working 'Sel Same' - Selects faces that have the same properties as the active face.
I added these based on goofsters work.
  
  Same UV Image - Goofster, I have optimized this a little
  Same Material
  Same Mode
  Same Normal *
  Same Area (2D surface area of the face) *
  Same VCol *
  Same UV-Coord *
  
  * - a limit variable wich allows you to set a fuzyness factor.

For anybody who wonders why do this- They are realy usefull for realtime models where you ofter want to...

select the faces from 10 colums that are roughly the same size but not linked (area)
all faces on the side of a roof (normal)
assign UV maps to a mesh that only has materials importer (Same Material)
Change the mode of a swag of faces you have indervidualy selected and changed (Mode)
change the vert colour for a lot of faces (changed mind on the colour) (vcol)
 
I have tested all extensivly and are stable AFAICT.
- Cam




Campbell Barton wrote:

> Hi, Im writing some code that compares the vert colours of faces with 
> eachother.
>
> The code dosent work beacure the colour values returned from the 
> selected  face colours is incorrect.
>
> eg,  i have 9 white faces on a plane, and when I print the colour 
> values is shows the last 2 faces to be a different colour.
>
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 255 255 255
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 255 255 255
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 255 255 255
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 255 255 255
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 255 255 255
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 255 255 255
> !Match Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 
> with 255 255 255 Comparing 255 255 255 with 255 255 255 Comparing 255 
> 255 255 with 76 66 89
> Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 with 255 
> 255 255 Comparing 255 255 255 with 76 66 89 Comparing 255 255 255 with 
> 63 128 0
> Comparing 255 255 255 with 255 255 255 Comparing 255 255 255 with 76 
> 66 89 Comparing 255 255 255 with 63 128 0 Comparing 255 255 255 with 0 
> 0 0
>
>
> Heres the code that assigns the colours
>
>
> var props
>
>     
>  /* Here are vars where we store the colours to compare */
>  /* extract of an email from Ton and Douglas Toltzman  What Ton is 
> saying is that there are 4, 8 bit components stored in a 32
>  bit, unsigned value.  I'm not sure of the order of components, but if 
> Ton
>  says "ABGR", then I'd presume the following would be correct
>  - Ton
>  Colors are 'packed' in an int, denoting bytes for ABGR respectively.
>  Put a char pointer to the color, and read the color components  
>  individually. Alpha is by default 255. */
>  char *packed_color_array;
>  /* face A- the active save */
>  short redA1, greenA1, blueA1, redA2, greenA2, blueA2, redA3, 
> greenA3,      blueA3, redA4, greenA4, blueA4,
>      redB1, greenB1, blueB1, redB2, greenB2, blueB2, redB3, greenB3, 
> blueB3, redB4, greenB4, blueB4;
> ____________________
>
>
>      /* make sure the face has at lease 3 point before we go on */
>      foundActFace=1;
>      /* face A- the active save */
>      packed_color_array = (char *) &tface[0].col;
>      redA1= packed_color_array[3];
>      greenA1= packed_color_array[2];
>      blueA1= packed_color_array[1];                  
> packed_color_array = (char *) &tface[1].col;
>      redA2= packed_color_array[3];
>      greenA2= packed_color_array[2];
>      blueA2= packed_color_array[1];
>         packed_color_array = (char *) &tface[2].col;
>      redA3 = packed_color_array[3];
>      greenA3 = packed_color_array[2];
>      blueA3 = packed_color_array[1];
>      if (mface->v4) {
>        packed_color_array = (char *) &tface[3].col;
>        redA4 = packed_color_array[3];
>        greenA4 = packed_color_array[2];
>        blueA4 = packed_color_array[1];
>      }
>
> Could anybody tel me why Im not getting all 255,255,255?
> - Thanks
>
>


-- 
Campbell J Barton

133 Hope Street
Geelong West, Victoria 3218 Australia

URL:    http://www.metavr.com
e-mail: cbarton@metavr.com
phone: AU (03) 5229 0241


--------------000904040801050002070706
Content-Type: text/plain;
 name="sel_same_face.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sel_same_face.txt"

? blender
? blender_back
? build.log
? config.opts
? source/blender/python/api2_2x/doc/Armature.pyc
? source/blender/python/api2_2x/doc/BGL.pyc
? source/blender/python/api2_2x/doc/BPY_API_233
? source/blender/python/api2_2x/doc/Blender.pyc
? source/blender/python/api2_2x/doc/Bone.pyc
? source/blender/python/api2_2x/doc/Camera.pyc
? source/blender/python/api2_2x/doc/Curve.pyc
? source/blender/python/api2_2x/doc/Draw.pyc
? source/blender/python/api2_2x/doc/Effect.pyc
? source/blender/python/api2_2x/doc/Image.pyc
? source/blender/python/api2_2x/doc/Ipo.pyc
? source/blender/python/api2_2x/doc/Lamp.pyc
? source/blender/python/api2_2x/doc/Lattice.pyc
? source/blender/python/api2_2x/doc/Library.pyc
? source/blender/python/api2_2x/doc/Material.pyc
? source/blender/python/api2_2x/doc/Mathutils.pyc
? source/blender/python/api2_2x/doc/Metaball.pyc
? source/blender/python/api2_2x/doc/NLA.pyc
? source/blender/python/api2_2x/doc/NMesh.pyc
? source/blender/python/api2_2x/doc/Noise.pyc
? source/blender/python/api2_2x/doc/Object.pyc
? source/blender/python/api2_2x/doc/Registry.pyc
? source/blender/python/api2_2x/doc/Render.pyc
? source/blender/python/api2_2x/doc/Scene.pyc
? source/blender/python/api2_2x/doc/Sys.pyc
? source/blender/python/api2_2x/doc/Text.pyc
? source/blender/python/api2_2x/doc/Texture.pyc
? source/blender/python/api2_2x/doc/Types.pyc
? source/blender/python/api2_2x/doc/Window.pyc
? source/blender/python/api2_2x/doc/World.pyc
Index: source/blender/include/BDR_editface.h
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/include/BDR_editface.h,v
retrieving revision 1.8
diff -u -r1.8 BDR_editface.h
--- source/blender/include/BDR_editface.h	5 Apr 2004 17:07:59 -0000	1.8
+++ source/blender/include/BDR_editface.h	18 Jul 2004 05:13:22 -0000
@@ -54,7 +54,13 @@
 void uv_autocalc_tface(void);
 void set_faceselect(void);
 void face_draw(void);
-void get_same_uv(void);  
+void get_same_uv(void); 
+void get_same_mat(void);
+void get_same_mode(void);
+void get_same_normal(void);
+void get_same_area(void); 
+void get_same_vcol(void);
+void get_same_uvco(void);  
 
 #endif /* BDR_EDITFACE_H */
 
Index: source/blender/src/editface.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/editface.c,v
retrieving revision 1.29
diff -u -r1.29 editface.c
--- source/blender/src/editface.c	16 Jul 2004 01:34:18 -0000	1.29
+++ source/blender/src/editface.c	18 Jul 2004 05:13:25 -0000
@@ -1564,9 +1564,8 @@
 	Object *ob;
 	Mesh *me;
 	TFace *tface;	
-	short a, foundtex=0;
-	Image *ima;
-	char uvname[160];
+	short a, foundActFace=0;
+	Image *ima; /* the active faces image */
 	
 	ob = OBACT;
 	if (!(ob->lay & G.vd->lay)) {
@@ -1575,43 +1574,531 @@
 	}
 	me = get_mesh(ob);
 	
-		
 	/* Search for the active face with a UV-Texture */
 	tface = me->tface;
-	a = me->totface;
-	while (a--) {		
-		if(tface->flag & TF_ACTIVE){			
-			ima=tface->tpage;
-			if(ima && ima->name){
-				strcpy(uvname,ima->name);			
-				a=0;
-				foundtex=1;
+	for (a = 0; a < me->totface; a++) { 
+		if(tface->flag & TF_ACTIVE){
+			if(tface->tpage){	
+				ima=tface->tpage;
+        foundActFace=1;
+        break;
 			}
 		}
 		tface++;
 	}		
 	
-	if(!foundtex) {
+	if(!foundActFace) {
 		error("No active face, or active face has no UV texture");
 		return;
 	}
 
 	/* select everything with the same texture */
 	tface = me->tface;
-	a = me->totface;
-	while (a--) {		
-		ima=tface->tpage;
-		if(ima && ima->name){
-			if(!strcmp(ima->name, uvname)){
-				tface->flag |= TF_SELECT;
+	for (a = 0; a < me->totface; a++) { 	
+		if (!(tface->flag & TF_HIDE)) { /* Is the face hidden */
+			if(ima == tface->tpage) tface->flag |= TF_SELECT;
+      /* else tface->flag &= ~TF_SELECT; */ /* Cam- Its better to allow the user to keep there current selection and just add to it */
+		}
+		tface++;
+	}
+	/* image window redraw */
+	allqueue(REDRAWIMAGE, 0);
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+ /* Selects all faces which have the same material as the active face
+ * @author	Roel Spruit, adapted by Campbell Barton
+ * @return	Void
+ * Errors:	- Active object not in this layer
+ *		- No active face or active face has no UV-texture			
+ */
+void get_same_mat(void)
+{
+	Object *ob;
+	Mesh *me;
+	TFace *tface;
+	MFace *mface;
+	short a, foundActFace=0, *mat, *active_mat;
+	ob = OBACT;
+	if (!(ob->lay & G.vd->lay)) {
+		error("The active object is not in this layer");
+		return;
+	}
+	me = get_mesh(ob);
+	
+	/* select everything with the same material */
+	tface= (((TFace*)me->tface)); /* This works for faces that dont have a UV image */
+  mface= (((MFace*)me->mface));
+	
+	/* Find the material of the active face */
+	for (a = 0; a < me->totface; a++) { 
+		if(tface->flag & TF_ACTIVE){
+			
+			if (tface->flag & TF_HIDE) { /* Is the active face hidden */
+				error("Active face is hidden");
+				return;
 			}
-			else tface->flag &= ~TF_SELECT;
+			
+			mat = mface->mat_nr;
+			foundActFace = 1;
+			active_mat = mat;
+      break;
 		}
-		else tface->flag &= ~TF_SELECT;
 		tface++;
+		mface++;
+	}		
+	
+	if(!foundActFace) {
+		error("No active face, or active face has no UV texture");
+		return;
+	}
+
+	tface= (((TFace*)me->tface));
+  mface= (((MFace*)me->mface));
+	
+	for (a = 0; a < me->totface; a++) { 
+		if (!(tface->flag & TF_HIDE)) { /* Is the face hidden */
+			mat=mface->mat_nr;
+			if(mat == active_mat) tface->flag |= TF_SELECT;
+			/* else tface->flag &= ~TF_SELECT; */ /* Cam- Its better to allow the user to keep there current selection and just add to it */
+		}
+		tface++;
+		mface++;
 	}
 	
+	/* image window redraw */
+	allqueue(REDRAWIMAGE, 0);
+	allqueue(REDRAWVIEW3D, 0);
+}
 
+ /* Selects all faces which have the same mode as the active face
+ * @author	Roel Spruit, adapted by Campbell Barton
+ * @return	Void
+ * Errors:	- Active object not in this layer
+ *		- No active face or active face has no UV-texture			
+ */
+void get_same_mode(void)
+{
+	Object *ob;
+	Mesh *me;
+	TFace *tface;
+	short a, foundActFace=0;
+	TFace *active_tface;
+	ob = OBACT;
+	if (!(ob->lay & G.vd->lay)) {
+		error("The active object is not in this layer");
+		return;
+	}
+	me = get_mesh(ob);
+	
+	/* select everything with the same material */
+	tface= (((TFace*)me->tface)); /* This works for faces that dont have a UV image */
+	
+	/* Find the material of the active face */
+  for (a = 0; a < me->totface; a++) { 
+		if(tface->flag & TF_ACTIVE){
+			
+			if (tface->flag & TF_HIDE) { /* Is the active face hidden */
+				error("Active face is hidden");
+				return;
+			}
+			
+      active_tface = tface;
+			foundActFace=1;
+      break;
+		}
+		tface++;
+	}		
+	
+	if(!foundActFace) {
+		error("No active face, or active face has no UV texture");
+		return;
+	}
+
+	tface= (((TFace*)me->tface));
+	
+	a = me->totface;
+	for (a = 0; a < me->totface; a++) { 
+		if (!(tface->flag & TF_HIDE)) { /* Is the face hidden */
+			if (tface->mode == active_tface->mode && tface->transp == active_tface->transp) tface->flag |= TF_SELECT;
+			/* else tface->flag &= ~TF_SELECT; */ /* Cam- Its better to allow the user to keep there current selection and just add to it */
+		}
+		tface++;
+	}
+	
+	/* image window redraw */
+	allqueue(REDRAWIMAGE, 0);
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+ /* Selects all faces which have the same normal as the active face
+ * @author	Roel Spruit, adapted by Campbell Barton
+ * @return	Void
+ * Errors:	- Active object not in this layer
+ *		- No active face or active face has no UV-texture			
+ */
+void get_same_normal(void)
+{
+	Object *ob;
+	Mesh *me;
+	TFace *tface;
+	MFace *mface;
+	short a, foundActFace=0;
+	float fNormal[3], active_fNormal[3], limit = 0.01;
+	
+	ob = OBACT;
+	if (!(ob->lay & G.vd->lay)) {
+		error("The active object is not in this layer");
+		return;
+	}
+	me = get_mesh(ob);
+	
+	/* select everything with the same material */
+	tface= (((TFace*)me->tface)); /* This works for faces that dont have a UV image */
+  mface= (((MFace*)me->mface));
+	
+	/* Find the normal of the active face */
+  for (a = 0; a < me->totface; a++) {
+    if(tface->flag & TF_ACTIVE){
+      if (tface->flag & TF_HIDE) { /* Is the active face hidden */
+        error("Active face is hidden");
+        return;
+      }
+      
+      /* Get Normals for actibe face- 4 vert face */
+      if (mface->v4) {
+        CalcNormFloat4((me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co, (me->mvert+mface->v4)->co, active_fNormal);
+      } else { /* 3 verts */
+        CalcNormFloat((me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co, active_fNormal);
+      } 
+      
+      foundActFace=1;
+      break;
+    }
+		tface++;
+		mface++;
+	}	
+	
+	if(!foundActFace) {
+		error("No active face, or active face has no UV texture");
+		return;
+	}
+
+	/* Pop up the user input for the normal limit modifier*/
+	if (fbutton(&limit, 0.0, 2.0, limit, 3, "Angle Limit: ") == 0) return;
+  
+	tface= (((TFace*)me->tface));
+  mface= (((MFace*)me->mface));
+	
+	for (a = 0; a < me->totface; a++) { 
+    if (!(tface->flag & TF_HIDE)) { /* Is the face hidden */
+      /* 4 vert face */
+      if (mface->v4) {
+        CalcNormFloat4((me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co, (me->mvert+mface->v4)->co, fNormal);
+      } else { /* 3 verts */
+        CalcNormFloat((me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co, fNormal);
+      }
+      
+      if (FloatCompare(fNormal, active_fNormal, limit)==1) tface->flag |= TF_SELECT;
+      /* else tface->flag &= ~TF_SELECT; */ /* Cam- Its better to allow the user to keep there current selection and just add to it */
+    }
+		tface++;
+		mface++;
+	}
+	
+	/* image window redraw */
+	allqueue(REDRAWIMAGE, 0);
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+ /* Selects all faces which have the same area as the active face
+ * @author	Roel Spruit, adapted by Campbell Barton
+ * @return	Void
+ * Errors:	- Active object not in this layer
+ *		- No active face or active face has no UV-texture			
+ */
+void get_same_area(void)
+{
+	Object *ob;
+	Mesh *me;
+	TFace *tface;
+	MFace *mface;
+	int a, foundActFace=0;
+	float act_area, area, limit = 0.01;
+	
+	ob = OBACT;
+	if (!(ob->lay & G.vd->lay)) {
+		error("The active object is not in this layer");
+		return;
+	}
+	me = get_mesh(ob);
+	
+	/* select everything with the same material */
+	tface= (((TFace*)me->tface)); /* This works for faces that dont have a UV image */
+  mface= (((MFace*)me->mface));
+	
+	/* Find the normal of the active face */
+	for (a = 0; a < me->totface; a++) { 
+    if(tface->flag & TF_ACTIVE) {
+      if (tface->flag & TF_HIDE) { /* Is the active face hidden */
+        error("Active face is hidden");
+        return;
+      }
+      /* Calculate the area of 4 vert face */
+      if (mface->v4) {
+        act_area = AreaT3Dfl( (me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co);
+        act_area = act_area + AreaT3Dfl( (me->mvert+mface->v1)->co, (me->mvert+mface->v3)->co, (me->mvert+mface->v4)->co);
+        foundActFace=1;
+        break;
+        
+      } else { /* Calculate the area of 3 verts */          
+        act_area = AreaT3Dfl( (me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co);
+        foundActFace=1;
+        break;
+      }
+    }
+		tface++;
+		mface++;
+	}
+	
+	if(!foundActFace) {
+		error("No active face, or active face has no UV texture");
+		return;
+	}
+  
+	/* Pop up the user input for the normal limit modifier*/
+	if (fbutton(&limit, 0.0, 10.0, limit, 3, "Area Limit: ") == 0) return;
+  
+	tface= (((TFace*)me->tface));
+  mface= (((MFace*)me->mface));
+	
+	for (a = 0; a < me->totface; a++) { 
+    if (!(tface->flag & TF_HIDE)) { /* Is the face hidden */
+      /* 4 vert face */
+      if (mface->v4) { /* work out a quad as 2 tri's */
+        area = AreaT3Dfl( (me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co);
+        area = area + AreaT3Dfl( (me->mvert+mface->v1)->co, (me->mvert+mface->v3)->co, (me->mvert+mface->v4)->co);
+      } else { /* 3 verts */          
+        area = AreaT3Dfl( (me->mvert+mface->v1)->co, (me->mvert+mface->v2)->co, (me->mvert+mface->v3)->co);
+      }
+      if (act_area + limit >= area && act_area - limit <= area ) tface->flag |= TF_SELECT;
+      /* else tface->flag &= ~TF_SELECT; */ /* Cam- Its better to allow the user to keep there current selection and just add to it */
+    }
+		tface++;
+		mface++;
+	}
+	
+	/* image window redraw */
+	allqueue(REDRAWIMAGE, 0);
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+ /* Selects all faces which have the same vert colour as the active face
+ * @author	Roel Spruit, adapted by Campbell Barton
+ * @return	Void
+ * Errors:	- Active object not in this layer
+ *		- No active face or active face has no UV-texture			
+ */
+void get_same_vcol(void)
+{
+	Object *ob;
+	Mesh *me;
+	TFace *tface;
+	MFace *mface;
+	short a, vertIter, actVertIter; /* iterators */
+  short foundActFace=0, vertCount, actVertCount;
+	float limit = 0.1;
+  int limit_int, actFaceCol[4][3], faceCol[4][3];
+  char *packed_color_array;
+  
+	ob = OBACT;
+	if (!(ob->lay & G.vd->lay)) {
+		error("The active object is not in this layer");
+		return;
+	}
+	me = get_mesh(ob);
+	
+	/* select everything with the same material */
+	tface= me->tface; /* This works for faces that dont have a UV image */
+  mface= (((MFace*)me->mface));
+  
+	/* Find the normal of the active face */
+	for (a = 0; a < me->totface; a++) { 
+    if(tface[a].flag & TF_ACTIVE) {
+      if (tface[a].flag & TF_HIDE) { /* Is the active face hidden */
+        error("Active face is hidden");
+        return;
+      }
+			/* make sure the face has at lease 3 point before we go on */
+      foundActFace=1;
+      
+      /* Assign colours to a var */
+      if (mface->v4) vertCount = 3;
+      else vertCount = 2;
+      actVertCount = vertCount;
+      
+      for (actVertIter = 0; actVertIter <= actVertCount; actVertIter++) { 
+        packed_color_array = (char *) &tface[a].col[actVertIter];
+        actFaceCol[actVertIter][0]= packed_color_array[1];
+        actFaceCol[actVertIter][1]= packed_color_array[2];
+        actFaceCol[actVertIter][2]= packed_color_array[3];
+      }
+			break;
+    }
+		mface++;
+	}
+	
+	if(!foundActFace) {
+		error("No active face, or active face has no UV texture");
+		return;
+	}
+  
+	/* Pop up the user input for the normal limit modifier*/
+	if (fbutton(&limit, 0.0, 1.0, limit, 3, "VCol Limit: ") == 0) return;
+  limit_int = (int)(limit * 255); /* this converts the limit into a useable int */
+  
+	tface= me->tface;
+  mface= (((MFace*)me->mface));
+	
+	for (a = 0; a < me->totface; a++) { 
+    if (!(tface[a].flag & TF_HIDE)) { /* Is the face hidden */
+
+      /* Assign colours to a var */
+      if (mface->v4) vertCount = 3;
+      else vertCount = 4;
+      
+      for (vertIter = 0; vertIter <= vertCount; vertIter++) { 
+        packed_color_array = (char *) &tface[a].col[vertIter];
+        faceCol[vertIter][0]= packed_color_array[1];
+        faceCol[vertIter][1]= packed_color_array[2];
+        faceCol[vertIter][2]= packed_color_array[3];
+      }
+      
+      foundActFace = 0; /* we reuse this var to see if the colours match */
+      
+      /* Test weather the 2 faces share vert colours */
+      for (actVertIter = 0; actVertIter <= actVertCount; actVertIter++) { 
+        for (vertIter = 0; vertIter <= vertCount; vertIter++) { 
+          
+          /* do we share a colour (will expand later) */
+          if (
+          actFaceCol[actVertIter][0] + limit_int >= faceCol[vertIter][0] && actFaceCol[actVertIter][0] - limit_int <= faceCol[vertIter][0] &&
+          actFaceCol[actVertIter][1] + limit_int >= faceCol[vertIter][1] && actFaceCol[actVertIter][1] - limit_int <= faceCol[vertIter][1] &&
+          actFaceCol[actVertIter][2] + limit_int >= faceCol[vertIter][2] && actFaceCol[actVertIter][2] - limit_int <= faceCol[vertIter][2] ) {
+            foundActFace++;
+            break;
+          }
+        }
+      }
+      
+      if (actVertCount <= foundActFace) tface[a].flag |= TF_SELECT;
+      /* else tface[a].flag &= ~TF_SELECT; */  /* Cam- Its better to allow the user to keep there current selection and just add to it */
+    }
+		mface++;
+	}
+	
+	/* image window redraw */
+	allqueue(REDRAWIMAGE, 0);
+	allqueue(REDRAWVIEW3D, 0);
+}
+
+
+
+ /* Selects all faces which have the same UV Coords as the active face
+ * @author	Roel Spruit, adapted by Campbell Barton
+ * @return	Void
+ * Errors:	- Active object not in this layer
+ *		- No active face or active face has no UV-texture			
+ */
+void get_same_uvco(void)
+{
+	Object *ob;
+	Mesh *me;
+	TFace *tface;
+	MFace *mface;
+	short a, vertIter, actVertIter; /* iterators */
+  short foundActFace=0, vertCount, actVertCount;
+  float limit = 0.1, actFaceUV[4][2], faceUV[4][2];
+  
+	ob = OBACT;
+	if (!(ob->lay & G.vd->lay)) {
+		error("The active object is not in this layer");
+		return;
+	}
+	me = get_mesh(ob);
+	
+	/* select everything with the same material */
+	tface= me->tface; /* This works for faces that dont have a UV image */
+  mface= (((MFace*)me->mface));
+  
+	/* Find the normal of the active face */
+	for (a = 0; a < me->totface; a++) { 
+    if(tface[a].flag & TF_ACTIVE) {
+      if (tface[a].flag & TF_HIDE) { /* Is the active face hidden */
+        error("Active face is hidden");
+        return;
+      }
+			/* make sure the face has at lease 3 point before we go on */
+      foundActFace=1;
+      
+      /* Assign colours to a var */
+      if (mface->v4) vertCount = 3;
+      else vertCount = 2;
+      actVertCount = vertCount;
+      
+      for (actVertIter = 0; actVertIter <= actVertCount; actVertIter++) { 
+        actFaceUV[actVertIter][0]= tface[a].uv[actVertIter][0];
+        actFaceUV[actVertIter][1]= tface[a].uv[actVertIter][1];
+      }
+			break;
+    }
+		mface++;
+	}
+	
+	if(!foundActFace) {
+		error("No active face, or active face has no UV texture");
+		return;
+	}
+  
+	/* Pop up the user input for the normal limit modifier*/
+	if (fbutton(&limit, 0.0, 1.0, limit, 3, "UV-Co Limit: ") == 0) return;
+  
+	tface= me->tface;
+  mface= (((MFace*)me->mface));
+	
+	for (a = 0; a < me->totface; a++) { 
+    if (!(tface[a].flag & TF_HIDE)) { /* Is the face hidden */
+
+      /* Assign colours to a var */
+      if (mface->v4) vertCount = 3;
+      else vertCount = 4;
+      
+      for (vertIter = 0; vertIter <= vertCount; vertIter++) { 
+        faceUV[vertIter][0]= tface[a].uv[vertIter][0];
+        faceUV[vertIter][1]= tface[a].uv[vertIter][1];
+      }
+      
+      foundActFace = 0; /* we reuse this var to see if the colours match */
+      
+      /* Test weather the 2 faces share vert colours */
+      for (actVertIter = 0; actVertIter <= actVertCount; actVertIter++) { 
+        for (vertIter = 0; vertIter <= vertCount; vertIter++) { 
+          
+          /* do we share a colour (will expand later) */
+          if (
+          actFaceUV[actVertIter][0] + limit >= faceUV[vertIter][0] && actFaceUV[actVertIter][0] - limit <= faceUV[vertIter][0] &&
+          actFaceUV[actVertIter][1] + limit >= faceUV[vertIter][1] && actFaceUV[actVertIter][1] - limit <= faceUV[vertIter][1] ) {
+            foundActFace++;
+            break;
+          }
+        }
+      }
+      
+      if (actVertCount <= foundActFace) tface[a].flag |= TF_SELECT;
+      /* else tface[a].flag &= ~TF_SELECT; */  /* Cam- Its better to allow the user to keep there current selection and just add to it */
+    }
+		mface++;
+	}
 	
 	/* image window redraw */
 	allqueue(REDRAWIMAGE, 0);
Index: source/blender/src/header_view3d.c
===================================================================
RCS file: /cvsroot/bf-blender/blender/source/blender/src/header_view3d.c,v
retrieving revision 1.59
diff -u -r1.59 header_view3d.c
--- source/blender/src/header_view3d.c	16 Jul 2004 02:10:52 -0000	1.59
+++ source/blender/src/header_view3d.c	18 Jul 2004 05:13:30 -0000
@@ -1041,6 +1041,24 @@
 		case 4: /* Select Same UV */
 			get_same_uv();
 			break;
+		case 5: /* Select Same Material */
+			get_same_mat();
+			break;
+		case 6: /* Select Same Mode */
+			get_same_mode();
+			break;
+		case 7: /* Select Same Normal */
+			get_same_normal();
+			break;
+		case 8: /* Select Same Area */
+			get_same_area();
+			break;
+		case 9: /* Select Same Vert colour */
+			get_same_vcol();
+			break;
+		case 10: /* Select Same Vert colour */
+			get_same_uvco();
+			break;
 	}
 	allqueue(REDRAWVIEW3D, 0);
 }
@@ -1059,7 +1077,16 @@
 	
 	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Select/Deselect All|A",				0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
 	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Inverse",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same UV",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+
+	uiDefBut(block, SEPR, 0, "",				0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same UV Image",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same Material",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same Mode",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same Normal",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same Area",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 8, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same Vert Col",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 9, "");
+	uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Same UV Coords",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
 
 	if(curarea->headertype==HEADERTOP) {
 		uiBlockSetDirection(block, UI_DOWN);
@@ -1072,6 +1099,7 @@
 	uiTextBoundsBlock(block, 50);
 	return block;
 }
+
 
 void do_view3d_edit_snapmenu(void *arg, int event)
 {

--------------000904040801050002070706--