[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38360] branches/soc-2011-onion/source/ blender: smart stitch

Antony Riakiotakis kalast at gmail.com
Wed Jul 13 14:44:00 CEST 2011


Revision: 38360
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38360
Author:   psy-fi
Date:     2011-07-13 12:44:00 +0000 (Wed, 13 Jul 2011)
Log Message:
-----------
smart stitch
====================
When this operator is over I swear I am going to have a party.

-group UvElements according to islands and store island information on them. This is crucial information for snapping islands together after stitching.
(Next commit will be first attempt with vertices.)
-do some minor corrections to functions.

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h
    branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h
    branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c
    branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c
    branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c

Modified: branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h
===================================================================
--- branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h	2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/blenkernel/BKE_mesh.h	2011-07-13 12:44:00 UTC (rev 38360)
@@ -53,6 +53,10 @@
 struct CustomData;
 struct DerivedMesh;
 struct Scene;
+struct UvVertMap;
+struct UvMapVert;
+struct UvVertMap2;
+struct UvElement;
 
 #ifdef __cplusplus
 extern "C" {
@@ -126,14 +130,22 @@
 	struct UvElement **vert;
 	struct UvElement *buf;
 	int numOfUVs;
+	int numOfIslands;
+	int *islandIndices;
 } UvVertMap2;
 
 typedef struct UvElement {
 	struct UvElement *next;
 	struct EditFace *face;
 	unsigned char tfindex, separate, flag;
+	unsigned short island;
 } UvElement;
 
+/* invalid island index is max short. If any one has the patience
+ * to make that many islands, he can bite me :p */
+#define INVALID_ISLAND 0xFFFF
+
+
 UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit);
 UvMapVert *get_uv_map_vert(UvVertMap *vmap, unsigned int v);
 void free_uv_vert_map(UvVertMap *vmap);

Modified: branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h
===================================================================
--- branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h	2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/include/ED_mesh.h	2011-07-13 12:44:00 UTC (rev 38360)
@@ -156,7 +156,7 @@
 struct UvMapVert *EM_get_uv_map_vert(struct UvVertMap *vmap, unsigned int v);
 void		EM_free_uv_vert_map(struct UvVertMap *vmap);
 
-struct UvVertMap2 *EM_make_uv_vert_map2(struct EditMesh *em, int selected, float *limit);
+struct UvVertMap2 *EM_make_uv_vert_map2(struct EditMesh *em, int selected);
 struct UvElement *EM_get_uv_map_vert_for_edge(struct UvVertMap2 *vmap, struct EditMesh *em, struct EditEdge *edge, int initVertexArray);
 void		EM_free_uv_vert_map2(struct UvVertMap2 *vmap);
 

Modified: branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c	2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/mesh/editmesh_lib.c	2011-07-13 12:44:00 UTC (rev 38360)
@@ -2357,7 +2357,8 @@
 	return vmap;
 }
 
-UvVertMap2 *EM_make_uv_vert_map2(EditMesh *em, int selected, float *limit)
+/* A specialized vert map used by stitch operator */
+UvVertMap2 *EM_make_uv_vert_map2(EditMesh *em, int selected)
 {
 	EditVert *ev;
 	EditFace *efa;
@@ -2366,13 +2367,18 @@
 	/* vars from original func */
 	UvVertMap2 *vmap;
 	UvElement *buf;
+	UvElement *islandbuf;
 	MTFace *tf;
 	unsigned int a;
-	int	i, totuv, nverts;
+	int	i,j, totuv, nverts, nislands = 0, islandbufsize = 0;
+	unsigned int *map;
+	/* for uv island creation */
+	EditFace **stack;
+	int stacksize = 0;
 
 	/* we need the vert */
-	for (ev= em->verts.first, totverts=0; ev; ev= ev->next, totverts++) {
-		ev->tmp.l = totverts;
+	for (ev= em->verts.first, i=0; ev; ev= ev->next, i++) {
+		ev->tmp.l = i;
 	}
 
 	totuv = 0;
@@ -2390,7 +2396,7 @@
 		return NULL;
 	}
 
-	vmap->vert= (UvElement**)MEM_callocN(sizeof(*vmap->vert)*totverts, "UvElement*");
+	vmap->vert= (UvElement**)MEM_callocN(sizeof(*vmap->vert)*em->totvert, "UvElement*");
 	buf= vmap->buf= (UvElement*)MEM_callocN(sizeof(*vmap->buf)*totuv, "UvElement");
 
 	if (!vmap->vert || !vmap->buf) {
@@ -2408,6 +2414,7 @@
 				buf->tfindex= i;
 				buf->face = efa;
 				buf->separate = 0;
+				buf->island = INVALID_ISLAND;
 
 				buf->next= vmap->vert[(*(&efa->v1 + i))->tmp.l];
 				vmap->vert[(*(&efa->v1 + i))->tmp.l]= buf;
@@ -2415,58 +2422,145 @@
 				buf++;
 			}
 		}
+		efa->tmp.l = INVALID_ISLAND;
 	}
 
-	if(limit)
-	{
-		/* sort individual uvs for each vert */
-		for(a=0, ev=em->verts.first; ev; a++, ev= ev->next) {
-			UvElement *newvlist= NULL, *vlist=vmap->vert[a];
-			UvElement *iterv, *v, *lastv, *next;
-			float *uv, *uv2;
 
-			while(vlist) {
-				v= vlist;
-				vlist= vlist->next;
-				v->next= newvlist;
-				newvlist= v;
+	/* sort individual uvs for each vert */
+	for(a=0, ev=em->verts.first; ev; a++, ev= ev->next) {
+		UvElement *newvlist= NULL, *vlist=vmap->vert[a];
+		UvElement *iterv, *v, *lastv, *next;
+		float *uv, *uv2;
 
-				efa = v->face;
+		while(vlist) {
+			v= vlist;
+			vlist= vlist->next;
+			v->next= newvlist;
+			newvlist= v;
+
+			efa = v->face;
+			tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+			uv = tf->uv[v->tfindex];
+
+			lastv= NULL;
+			iterv= vlist;
+
+			while(iterv) {
+				next= iterv->next;
+				efa = iterv->face;
 				tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-				uv = tf->uv[v->tfindex];
+				uv2 = tf->uv[iterv->tfindex];
+					if(fabsf(uv[0]-uv2[0]) < STD_UV_CONNECT_LIMIT && fabsf(uv[1]-uv2[1]) < STD_UV_CONNECT_LIMIT) {
+					if(lastv) lastv->next= next;
+					else vlist= next;
+					iterv->next= newvlist;
+					newvlist= iterv;
+				}
+				else
+					lastv=iterv;
+					iterv= next;
+			}
+				newvlist->separate = 1;
+		}
+			vmap->vert[a]= newvlist;
+	}
 
-				lastv= NULL;
-				iterv= vlist;
+	/* At this point, every UvElement in vert points to a UvElement sharing the same vertex. Now we should sort uv's in islands. */
 
-				while(iterv) {
-					next= iterv->next;
-					efa = iterv->face;
-					tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-					uv2 = tf->uv[iterv->tfindex];
+	/* map holds the map from current vmap->buf to the new, sorted map*/
+	map = MEM_mallocN(sizeof(*map)*totuv, "uvelement_remap");
+	stack = MEM_mallocN(sizeof(*stack)*em->totface, "uv_island_face_stack");
+	islandbuf = MEM_callocN(sizeof(*islandbuf)*totuv, "uvelement_island_buffer");
+	if(!map || !stack || !islandbuf){
+		if(stack)
+			MEM_freeN(stack);
+		if(map)
+			MEM_freeN(map);
+		if(islandbuf)
+			MEM_freeN(islandbuf);
+		EM_free_uv_vert_map2(vmap);
+		return NULL;
+	}
+	for(i = 0; i < totuv; i++){
+		if(vmap->buf[i].island == INVALID_ISLAND){
+			vmap->buf[i].island = nislands;
+			stack[0] = vmap->buf[i].face;
+			stack[0]->tmp.l = 0;
+			stacksize=1;
 
-					if(fabsf(uv[0]-uv2[0]) < limit[0] && fabsf(uv[1]-uv2[1]) < limit[1]) {
-						if(lastv) lastv->next= next;
-						else vlist= next;
-						iterv->next= newvlist;
-						newvlist= iterv;
+			while(stacksize > 0){
+				efa = stack[--stacksize];
+				nverts = efa->v4? 4 : 3;
+				for(j = 0; j < nverts; j++){
+					UvElement *element, *initelement = vmap->vert[(*(&efa->v1 + j))->tmp.l];
+					for(element = initelement; element; element = element->next){
+						if(element->separate){
+							initelement = element;
+						}
+						if(element->face == efa){
+							/* found the uv corresponding to our face and vertex. Now fill it to the buffer */
+							element->island = nislands;
+							map[element - vmap->buf] = islandbufsize;
+							islandbuf[islandbufsize].tfindex = element->tfindex;
+							islandbuf[islandbufsize].face = element->face;
+							islandbuf[islandbufsize].separate = element->separate;
+							islandbufsize++;
+
+							for(element = initelement; element; element = element->next){
+								if(element->separate && element != initelement){
+									break;
+								}
+								if(element->face->tmp.l == INVALID_ISLAND){
+									stack[stacksize++] = element->face;
+									element->face->tmp.l = nislands;
+								}
+							}
+							break;
+						}
 					}
-					else
-						lastv=iterv;
-
-					iterv= next;
 				}
-
-				newvlist->separate = 1;
 			}
 
-			vmap->vert[a]= newvlist;
+			nislands++;
 		}
 	}
+	/* Remap */
+	for(i = 0; i < em->totvert; i++){
+		vmap->vert[i] = &islandbuf[map[vmap->vert[i] - vmap->buf]];
+	}
+	vmap->islandIndices = MEM_callocN(sizeof(*vmap->islandIndices)*nislands,"UvVertMap2_island_indices");
+	if(!vmap->islandIndices)
+	{
+		MEM_freeN(islandbuf);
+		MEM_freeN(stack);
+		MEM_freeN(map);
+		EM_free_uv_vert_map2(vmap);
+	}
 
+
+	j = 0;
+	for(i = 0; i < totuv; i++){
+		UvElement *element = vmap->buf[i].next;
+		if(element == NULL){
+			islandbuf[map[i]].next = NULL;
+			continue;
+		}
+		islandbuf[map[i]].next = &islandbuf[map[element - vmap->buf]];
+		if(islandbuf[i].island != j){
+			j++;
+			vmap->islandIndices[j] = i;
+		}
+	}
+	MEM_freeN(vmap->buf);
+
+	vmap->buf = islandbuf;
+	vmap->numOfIslands = nislands;
+	MEM_freeN(stack);
+	MEM_freeN(map);
 	return vmap;
 }
-
-/* Will return the UV for which uvi and uvi+1 belong to given edge */
+/* The function below is buggy, should check face first. correct before use */
+/* Will return the UV for which uvi and uvi+1 belong to given edge
 UvElement *EM_get_uv_map_vert_for_edge(UvVertMap2 *vmap, EditMesh *em, EditEdge *edge, int initVertexArray)
 {
 	int i;
@@ -2497,6 +2591,7 @@
 	}
 	return NULL;
 }
+*/
 
 UvMapVert *EM_get_uv_map_vert(UvVertMap *vmap, unsigned int v)
 {
@@ -2517,6 +2612,7 @@
 	if (vmap) {
 		if (vmap->vert) MEM_freeN(vmap->vert);
 		if (vmap->buf) MEM_freeN(vmap->buf);
+		if (vmap->islandIndices) MEM_freeN(vmap->islandIndices);
 		MEM_freeN(vmap);
 	}
 }

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c	2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_island_manager.c	2011-07-13 12:44:00 UTC (rev 38360)
@@ -1,5 +1,5 @@
 /*
- * $Id: uvedit_island_manager.cpp 38000 2011-07-01 12:06:32Z psy-fi $
+ * $Id: uvedit_island_manager.c 38360 2011-07-01 12:06:32Z psy-fi $
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c	2011-07-13 12:16:45 UTC (rev 38359)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_ops.c	2011-07-13 12:44:00 UTC (rev 38360)
@@ -22,7 +22,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): none yet.
+ * Contributor(s): Antony Riakiotakis.
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -1735,12 +1735,10 @@
 	StitchState *stitch_state = MEM_mallocN(sizeof(StitchState), "stitch_state");
 	StitchPreviewer *preview = stitch_preview_init();
 	EditMesh *em;
-	float limit[2];

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list