[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