Seam Cutting in Faceselect Mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 8 Feb 2006 21:01:00 +0000 (21:01 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 8 Feb 2006 21:01:00 +0000 (21:01 +0000)
- Mark Border Seam: mark edges on the border of face selection as seam.
- Clear Seam: clears seams in selected faces.
Hotkey: Ctrl+E

- Alt+RMB Click: mark/clear edge as seam
- Alt+Shift+RMB Click: mark/clear seams along the shortest/straightest path
  from last marked seam. The cost of the path also includes some measure of
  'straightness' next to the typical distance to make things work more
  predicatble and edgeloop friendly. Note that this cuts a path from edge to
  edge, not vertex to vertex. That gives some nice control over the direction
  of the seam.

Also includes:

- Removed old LSCM code.
- Fix updates glitches with DerivedMesh/Subsurf drawing in FaceSelect mode.
  Now there's a drawMappedFacesTex instead of drawFacesTex.
- Minimize Stretch menu entry called Limit Stitch.
- Removed the lasttface global, was being set before it was used anyway, so
  might as wel return from a function.
- Moved some backbuf sampling code to drawview.c from editmesh, so it can be
  used by Faceselect and VPaint.
- Use BLI_heap in parametrizer.c.

27 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/include/BDR_drawmesh.h
source/blender/include/BDR_editface.h
source/blender/include/BDR_unwrapper.h
source/blender/include/BSE_drawview.h
source/blender/include/butspace.h
source/blender/makesdna/DNA_mesh_types.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/src/butspace.c
source/blender/src/buttons_editing.c
source/blender/src/drawimage.c
source/blender/src/drawmesh.c
source/blender/src/drawobject.c
source/blender/src/drawview.c
source/blender/src/editface.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/header_image.c
source/blender/src/header_view3d.c
source/blender/src/parametrizer.c
source/blender/src/parametrizer_intern.h
source/blender/src/space.c
source/blender/src/unwrapper.c
source/blender/src/view.c
source/blender/src/vpaint.c

index 1e62dacc1587a28b6f5188a5eb91135ae6faf980..1b594e6d49275d6116cd9d5d55850d2b6b457a1b 100644 (file)
@@ -47,7 +47,6 @@
 
 struct MVert;
 struct Object;
-struct TFace;
 struct EditMesh;
 struct DispListMesh;
 struct ModifierData;
@@ -144,7 +143,7 @@ struct DerivedMesh {
                        /* Draw all faces uses TFace 
                         *  o Drawing options too complicated to enumerate, look at code.
                         */
-       void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(struct TFace *tf, int matnr));
+       void (*drawMappedFacesTex)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int matnr), void *userData);
 
                        /* Draw mapped faces (no color, or texture)
                         *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-face-index, drawSmooth_r) returns true
index 1a26b52a0aa145aaa6a4e298eef17acc0bba0ddd..c51a50dd313ae8be9fe5e3545aee49893161dc8b 100644 (file)
@@ -366,7 +366,7 @@ static void meshDM_drawFacesColored(DerivedMesh *dm, int useTwoSide, unsigned ch
        glShadeModel(GL_FLAT);
        glDisable(GL_CULL_FACE);
 }
-static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)
+static void meshDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData
 {
        MeshDerivedMesh *mdm = (MeshDerivedMesh*) dm;
        Mesh *me = mdm->me;
@@ -382,7 +382,7 @@ static void meshDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
                int flag;
                unsigned char *cp= NULL;
                
-               flag = setDrawParams(tf, mf->mat_nr);
+               flag = setDrawParams(userData, i, mf->mat_nr);
 
                if (flag==0) {
                        continue;
@@ -535,7 +535,7 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
        
        mdm->dm.drawFacesSolid = meshDM_drawFacesSolid;
        mdm->dm.drawFacesColored = meshDM_drawFacesColored;
-       mdm->dm.drawFacesTex = meshDM_drawFacesTex;
+       mdm->dm.drawMappedFacesTex = meshDM_drawMappedFacesTex;
        mdm->dm.drawMappedFaces = meshDM_drawMappedFaces;
 
        mdm->dm.drawMappedEdges = meshDM_drawMappedEdges;
@@ -1202,7 +1202,8 @@ static void ssDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
        
 #undef PASSVERT
 }
-static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) 
+
+static void ssDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData) 
 {
        SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
        DispListMesh *dlm = ssdm->dlm;
@@ -1210,7 +1211,7 @@ static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, i
        MFace *mface= dlm->mface;
        TFace *tface = dlm->tface;
        float *nors = dlm->nors;
-       int a;
+       int a, index=-1;
        
        for (a=0; a<dlm->totface; a++) {
                MFace *mf= &mface[a];
@@ -1218,7 +1219,9 @@ static void ssDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, i
                int flag;
                unsigned char *cp= NULL;
                
-               flag = setDrawParams(tf, mf->mat_nr);
+               if (mf->flag&ME_FACE_STEPINDEX) index++;
+
+               flag = setDrawParams(userData, index, mf->mat_nr);
 
                if (flag==0) {
                        continue;
@@ -1401,7 +1404,7 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
        
        ssdm->dm.drawFacesSolid = ssDM_drawFacesSolid;
        ssdm->dm.drawFacesColored = ssDM_drawFacesColored;
-       ssdm->dm.drawFacesTex = ssDM_drawFacesTex;
+       ssdm->dm.drawMappedFacesTex = ssDM_drawMappedFacesTex;
        ssdm->dm.drawMappedFaces = ssDM_drawMappedFaces;
 
                /* EM functions */
@@ -1624,7 +1627,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
        ModifierData *md;
        float (*deformedVerts)[3] = NULL;
        DerivedMesh *dm;
-       int i, numVerts, cageIndex = modifiers_getCageIndex(ob, NULL);
+       int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
 
        modifiers_clearErrors(ob);
 
index d0b741123b5991caefdf5b4123acb5991772beed..e7870fe150e1e61a2430446ad72925a5a9ebaa7f 100644 (file)
@@ -1376,7 +1376,7 @@ static void ccgDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned ch
 
        ccgFaceIterator_free(fi);
 }
-static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr)) {
+static void ccgDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawParams)(void *userData, int index, int matnr), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
@@ -1395,7 +1395,8 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
                MFace *mf = &mface[index];
                TFace *tf = tface?&tface[index]:NULL;
                unsigned char *cp= NULL;
-               int flag = setDrawParams(tf, mf->mat_nr);
+               int findex = ccgDM_getFaceMapIndex(ccgdm, ss, f); 
+               int flag = (findex == -1)? 0: setDrawParams(userData, findex, mf->mat_nr);
 
                if (flag==0) {
                        continue;
@@ -1662,7 +1663,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, int d
        ccgdm->dm.drawLooseEdges = ccgDM_drawLooseEdges;
        ccgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid;
        ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
-       ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
+       ccgdm->dm.drawMappedFacesTex = ccgDM_drawMappedFacesTex;
        ccgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces;
 
        ccgdm->dm.drawMappedEdgesInterp = ccgDM_drawMappedEdgesInterp;
index c6bcf061fcc1a8224eaea0aa0035223b21bc16d1..7463cffa6ef49649b95cd9d102273375b277c846 100644 (file)
@@ -37,6 +37,7 @@ struct Image;
 struct TFace;
 struct Object;
 struct Mesh;
+struct EdgeHash;
 
 /**
  * Enables or disable mipmapping for realtime images (textures).
@@ -74,6 +75,7 @@ void free_all_realtime_images(void);
 void make_repbind(struct Image *ima);
 int set_tpage(struct TFace *tface);
 void draw_tface_mesh(struct Object *ob, struct Mesh *me, int dt);
+struct EdgeHash *get_tface_mesh_marked_edge_info(struct Mesh *me);
 void init_realtime_GL(void); 
 
 #endif /* BDR_DRAWMESH_H */
index 0f817c172275e66d3f462bf03dfd725486790f65..9b260a3df47b69dbbc9f307ba185a8e086234589 100644 (file)
@@ -36,7 +36,7 @@
 struct TFace;
 struct Mesh;
 
-void set_lasttface(void);
+struct TFace *get_active_tface(void);
 void calculate_uv_map(unsigned short mapmode);
 void default_uv(float uv[][2], float size);
 void default_tface(struct TFace *tface);
@@ -49,13 +49,13 @@ void selectswap_tface(void);
 void rotate_uv_tface(void);
 void mirror_uv_tface(void);
 void minmax_tface(float *min, float *max);
-int face_pick(struct Mesh *me, short x, short y, unsigned int *index);
 void face_select(void);
 void face_borderselect(void);
 void uv_autocalc_tface(void);
 void set_faceselect(void);
 void face_draw(void);
 void get_same_uv(void);  
+void seam_mark_clear_tface(short mode);
 
 #endif /* BDR_EDITFACE_H */
 
index 6107eba15a26151da034804805bcf69d2624d098..396bb17cff050886893d0755213b5c1652d800e6 100644 (file)
@@ -36,8 +36,7 @@
 void set_seamtface(void); /* set TF_SEAM flags in tfaces */
 void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index);
 
-void unwrap_lscm(void); /* unwrap faces selected in 3d view */
-void unwrap_lscm_new(void);
+void unwrap_lscm(short seamcut); /* unwrap faces selected in 3d view */
 void minimize_stretch_tface_uv(void); /* optimize faces selected in uv editor */
 void smooth_area_tface_uv(void);
 
index 1d04062fb8d3b96636557ff4924f18a057644d07..1174aee6c64f1e7867a39f5ffad29a859872cc79 100644 (file)
@@ -37,6 +37,7 @@ struct Object;
 struct BGpic;
 struct rcti;
 struct ScrArea;
+struct ImBuf;
 
 void setalpha_bgpic(struct BGpic *bgpic);
 void default_gl_light(void);
@@ -52,6 +53,11 @@ void do_viewbuts(unsigned short event);
 void add_view3d_after(struct View3D *v3d, struct Base *base, int type);
 
 void backdrawview3d(int test);
+void check_backbuf(void);
+unsigned int sample_backbuf(int x, int y);
+struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax);
+unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist);;
+
 void drawview3dspace(struct ScrArea *sa, void *spacedata);
 void drawview3d_render(struct View3D *v3d, int winx, int winy);
 
index 184763fd9da361dd64b4af9b78858aecdcbdd1f9..6d6da4bc8560958c3c2ec80b042cc2bc588fd7c6 100644 (file)
@@ -86,6 +86,7 @@ extern void do_latticebuts(unsigned short event);
 extern void do_fpaintbuts(unsigned short event);
 extern void do_cambuts(unsigned short event);
 extern void do_armbuts(unsigned short event);
+extern void do_uvautocalculationbuts(unsigned short event);
 
 extern char *get_vertexgroup_menustr(struct Object *ob);       // used in object buttons
 
@@ -113,11 +114,6 @@ extern void do_scriptbuts(unsigned short event);
 /* ipowindow */
 extern void do_ipobuts(unsigned short event);  // drawipo.c (bad! ton)
 
-/* uvautocalculation */
-void do_uvautocalculationbuts(unsigned short event);
-void get_uvautocalculationsettings(float *radius,float *cubesize, int *mapdir, int *mapalign);
-
-
 /* butspace.c */
 void test_meshpoin_but(char *name, struct ID **idpp);
 void test_obpoin_but(char *name, struct ID **idpp);
index f6f16b94f3a72b0ab40e6cfd636cebe5a30815bb..e5496c895bc4b23cc67071737fb3a2556cbc61e7 100644 (file)
@@ -155,14 +155,14 @@ typedef struct Mesh {
 #define TF_SUB         3
 
 /* tface->unwrap */
-#define TF_SEAM1       1
-#define TF_SEAM2       2
-#define TF_SEAM3       4
-#define TF_SEAM4       8
-#define TF_PIN1            16
-#define TF_PIN2            32
-#define TF_PIN3            64
-#define TF_PIN4            128
+#define TF_DEPRECATED1 1
+#define TF_DEPRECATED2 2
+#define TF_DEPRECATED3 4
+#define TF_DEPRECATED4 8
+#define TF_PIN1                    16
+#define TF_PIN2                    32
+#define TF_PIN3                        64
+#define TF_PIN4                128
 
 #define MESH_MAX_VERTS 2000000000L
 
index 9fe5a3acacf17041b088020134678a72008875fc..834c206d8e0e19d39b503490bc06225d2c6d7199 100644 (file)
@@ -85,6 +85,7 @@ typedef struct MSticky {
                                                // reserve 16 for ME_HIDE
 #define ME_EDGERENDER          (1<<5)
 #define ME_LOOSEEDGE           (1<<7)
+#define ME_SEAM_LAST           (1<<8)
 #define ME_EDGE_STEPINDEX      (1<<15)
 
 /* puno = vertexnormal (mface) */
index e3f6a1d5515e8ce67a43fbc65b667582b1d5d98d..2d293966e793a27da61dc899246a7394570508dd 100644 (file)
@@ -580,7 +580,7 @@ void do_butspace(unsigned short event)
                do_constraintbuts(event);
        }
        else if(event<=B_UVAUTOCALCBUTS) {
-               do_uvautocalculationbuts(event);
+               do_uvcalculationbuts(event);
        }
        else if(event<=B_EFFECTSBUTS) {
                do_effects_panels(event);
index 028f3d43540e609edac3e97f413e816b081b570a..9077aae86aa1c536e36261602bde208f262d406f 100644 (file)
@@ -3540,7 +3540,8 @@ void do_fpaintbuts(unsigned short event)
        Mesh *me;
        Object *ob;
        bDeformGroup *defGroup;
-       extern TFace *lasttface; /* caches info on tface bookkeeping ?*/
+       TFace *activetf, *tf;
+       int a;
        extern VPaint Gwp;         /* from vpaint */
 
        ob= OBACT;
@@ -3555,42 +3556,37 @@ void do_fpaintbuts(unsigned short event)
        case B_COPY_TF_UV:
        case B_COPY_TF_COL:
        case B_COPY_TF_TEX:
-               me= get_mesh(ob);
-               if(me && me->tface) {
-/*                     extern TFace *lasttface; */
-                       TFace *tface= me->tface;
-                       int a= me->totface;
-
-                       set_lasttface();
-                       if(lasttface) {
-
-                               while(a--) {
-                                       if(tface!=lasttface && (tface->flag & TF_SELECT)) {
-                                               if(event==B_COPY_TF_MODE) {
-                                                       tface->mode= lasttface->mode;
-                                                       tface->transp= lasttface->transp;
-                                               }
-                                               else if(event==B_COPY_TF_UV) {
-                                                       memcpy(tface->uv, lasttface->uv, sizeof(tface->uv));
-                                                       tface->tpage= lasttface->tpage;
-                                                       tface->tile= lasttface->tile;
+               me = get_mesh(OBACT);
+               activetf = get_active_tface();
+
+               if(me && activetf) {
+                       for (a=0, tf=me->tface; a < me->totface; a++, tf++) {
+                               if(tf!=activetf && (tf->flag & TF_SELECT)) {
+                                       if(event==B_COPY_TF_MODE) {
+                                               tf->mode= activetf->mode;
+                                               tf->transp= activetf->transp;
+                                       }
+                                       else if(event==B_COPY_TF_UV) {
+                                               memcpy(tf->uv, activetf->uv, sizeof(tf->uv));
+                                               tf->tpage= activetf->tpage;
+                                               tf->tile= activetf->tile;
 
-                                                       if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
-                                                       else tface->mode &= ~TF_TILES;
+                                               if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
+                                               else tf->mode &= ~TF_TILES;
 
-                                               }
-                                               else if(event==B_COPY_TF_TEX) {
-                                                       tface->tpage= lasttface->tpage;
-                                                       tface->tile= lasttface->tile;
+                                       }
+                                       else if(event==B_COPY_TF_TEX) {
+                                               tf->tpage= activetf->tpage;
+                                               tf->tile= activetf->tile;
 
-                                                       if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
-                                                       else tface->mode &= ~TF_TILES;
-                                               }
-                                               else if(event==B_COPY_TF_COL) memcpy(tface->col, lasttface->col, sizeof(tface->col));
+                                               if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
+                                               else tf->mode &= ~TF_TILES;
                                        }
-                                       tface++;
+                                       else if(event==B_COPY_TF_COL)
+                                               memcpy(tf->col, activetf->col, sizeof(tf->col));
                                }
                        }
+
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
                        do_shared_vertexcol(me);
                        allqueue(REDRAWVIEW3D, 0);
@@ -3616,17 +3612,17 @@ void do_fpaintbuts(unsigned short event)
                break;
 
        case B_TFACE_HALO:
-               set_lasttface();
-               if(lasttface) {
-                       lasttface->mode &= ~TF_BILLBOARD2;
+               activetf = get_active_tface();
+               if(activetf) {
+                       activetf->mode &= ~TF_BILLBOARD2;
                        allqueue(REDRAWBUTSEDIT, 0);
                }
                break;
 
        case B_TFACE_BILLB:
-               set_lasttface();
-               if(lasttface) {
-                       lasttface->mode &= ~TF_BILLBOARD;
+               activetf = get_active_tface();
+               if(activetf) {
+                       activetf->mode &= ~TF_BILLBOARD;
                        allqueue(REDRAWBUTSEDIT, 0);
                }
                break;
@@ -3786,38 +3782,37 @@ static void editing_panel_mesh_texface(void)
 {
        extern VPaint Gvp;         /* from vpaint */
        uiBlock *block;
-       extern TFace *lasttface;
+       TFace *tf;
 
        block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_texface", UI_EMBOSS, UI_HELV, curarea->win);
        if(uiNewPanel(curarea, block, "Texture face", "Editing", 960, 0, 318, 204)==0) return;
 
-       set_lasttface();        // checks for ob type
-       if(lasttface) {
-
+       tf = get_active_tface();
+       if(tf) {
                uiBlockBeginAlign(block);
-               uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex",  600,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Render face with texture");
-               uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles",      660,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use tilemode for face");
-               uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light",       720,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use light for face");
-               uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Make face invisible");
-               uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &lasttface->mode, 0, 0, 0, 0, "Use face for collision detection");
+               uiDefButBitS(block, TOG, TF_TEX, B_REDR_3D_IMA, "Tex",  600,160,60,19, &tf->mode, 0, 0, 0, 0, "Render face with texture");
+               uiDefButBitS(block, TOG, TF_TILES, B_REDR_3D_IMA, "Tiles",      660,160,60,19, &tf->mode, 0, 0, 0, 0, "Use tilemode for face");
+               uiDefButBitS(block, TOG, TF_LIGHT, REDRAWVIEW3D, "Light",       720,160,60,19, &tf->mode, 0, 0, 0, 0, "Use light for face");
+               uiDefButBitS(block, TOG, TF_INVISIBLE, REDRAWVIEW3D, "Invisible",780,160,60,19, &tf->mode, 0, 0, 0, 0, "Make face invisible");
+               uiDefButBitS(block, TOG, TF_DYNAMIC, REDRAWVIEW3D, "Collision", 840,160,60,19, &tf->mode, 0, 0, 0, 0, "Use face for collision detection");
 
                uiBlockBeginAlign(block);
-               uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared",  600,135,60,19, &lasttface->mode, 0, 0, 0, 0, "Blend vertex colours across face when vertices are shared");
-               uiDefButBitS(block, TOG, TF_TWOSIDE, REDRAWVIEW3D, "Twoside",660,135,60,19, &lasttface->mode, 0, 0, 0, 0, "Render face twosided");
-               uiDefButBitS(block, TOG, TF_OBCOL, REDRAWVIEW3D, "ObColor",720,135,60,19, &lasttface->mode, 0, 0, 0, 0, "Use ObColor instead of vertex colours");
+               uiDefButBitS(block, TOG, TF_SHAREDCOL, REDRAWVIEW3D, "Shared",  600,135,60,19, &tf->mode, 0, 0, 0, 0, "Blend vertex colours across face when vertices are shared");
+               uiDefButBitS(block, TOG, TF_TWOSIDE, REDRAWVIEW3D, "Twoside",660,135,60,19, &tf->mode, 0, 0, 0, 0, "Render face twosided");
+               uiDefButBitS(block, TOG, TF_OBCOL, REDRAWVIEW3D, "ObColor",720,135,60,19, &tf->mode, 0, 0, 0, 0, "Use ObColor instead of vertex colours");
 
                uiBlockBeginAlign(block);
                
-               uiDefButBitS(block, TOG, TF_BILLBOARD, B_TFACE_HALO, "Halo",    600,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Screen aligned billboard");
-               uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
-               uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Face is used for shadow");
-               uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &lasttface->mode, 0, 0, 0, 0, "Enable bitmap text on face");
+               uiDefButBitS(block, TOG, TF_BILLBOARD, B_TFACE_HALO, "Halo",    600,110,60,19, &tf->mode, 0, 0, 0, 0, "Screen aligned billboard");
+               uiDefButBitS(block, TOG, TF_BILLBOARD2, B_TFACE_BILLB, "Billboard",660,110,60,19, &tf->mode, 0, 0, 0, 0, "Billboard with Z-axis constraint");
+               uiDefButBitS(block, TOG, TF_SHADOW, REDRAWVIEW3D, "Shadow", 720,110,60,19, &tf->mode, 0, 0, 0, 0, "Face is used for shadow");
+               uiDefButBitS(block, TOG, TF_BMFONT, REDRAWVIEW3D, "Text", 780,110,60,19, &tf->mode, 0, 0, 0, 0, "Enable bitmap text on face");
 
                uiBlockBeginAlign(block);
                uiBlockSetCol(block, TH_BUT_SETTING1);
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque",   600,80,60,19, &lasttface->transp, 2.0, 0.0, 0, 0, "Render colour of textured face as colour");
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Add",              660,80,60,19, &lasttface->transp, 2.0, 1.0, 0, 0, "Render face transparent and add colour of face");
-               uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha",    720,80,60,19, &lasttface->transp, 2.0, 2.0, 0, 0, "Render polygon transparent, depending on alpha channel of the texture");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Opaque",   600,80,60,19, &tf->transp, 2.0, 0.0, 0, 0, "Render colour of textured face as colour");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Add",              660,80,60,19, &tf->transp, 2.0, 1.0, 0, 0, "Render face transparent and add colour of face");
+               uiDefButC(block, ROW, REDRAWVIEW3D, "Alpha",    720,80,60,19, &tf->transp, 2.0, 2.0, 0, 0, "Render polygon transparent, depending on alpha channel of the texture");
 
                uiBlockSetCol(block, TH_AUTO);
 
@@ -3832,29 +3827,9 @@ static void editing_panel_mesh_texface(void)
        }
 }
 
-void do_uvautocalculationbuts(unsigned short event)
+void do_uvcalculationbuts(unsigned short event)
 {
-       switch(event) {
-       case B_UVAUTO_STD1:
-       case B_UVAUTO_STD2:
-       case B_UVAUTO_STD4:
-       case B_UVAUTO_STD8:
-       case B_UVAUTO_CUBE:
-               calculate_uv_map(event);
-               break;
-       case B_UVAUTO_BOUNDS1:
-       case B_UVAUTO_BOUNDS2:
-       case B_UVAUTO_BOUNDS4:
-       case B_UVAUTO_BOUNDS8:
-       case B_UVAUTO_SPHERE:
-       case B_UVAUTO_CYLINDER:
-       case B_UVAUTO_WINDOW:
-               if(select_area(SPACE_VIEW3D)) calculate_uv_map(event);
-               break;
-       case B_UVAUTO_UNWRAP:
-               unwrap_lscm();
-               break;
-       }
+       /* nothing to do here */
 }
 
 static void editing_panel_mesh_uvautocalculation(void)
@@ -3877,9 +3852,8 @@ static void editing_panel_mesh_uvautocalculation(void)
        row-= 4*butHB+butS;
 
        uiBlockBeginAlign(block);
-       uiDefButS(block, MENU, REDRAWBUTSEDIT, "Unwrapper%t|Conformal%x0|Angle Based%x1|Conformal (Old)%x2",100,row,200,butH, &G.scene->toolsettings->unwrapper, 0, 0, 0, 0, "Unwrap method");
-       if (G.scene->toolsettings->unwrapper != 2)
-               uiDefButBitS(block, TOG, 1, B_NOP, "Fill Holes",100,row-butHB,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0,  "Fill holes to prevent internal overlaps");
+       uiDefButS(block, MENU, REDRAWBUTSEDIT, "Unwrapper%t|Conformal%x0|Angle Based%x1",100,row,200,butH, &G.scene->toolsettings->unwrapper, 0, 0, 0, 0, "Unwrap method");
+       uiDefButBitS(block, TOG, 1, B_NOP, "Fill Holes",100,row-butHB,200,butH,&G.scene->toolsettings->uvcalc_flag, 0, 0, 0, 0,  "Fill holes to prevent internal overlaps");
        uiBlockEndAlign(block);
        row-= 2*butHB+butS;
 
index af34d6ae8493dafeafee5e3f2329cadcc2525187..154d12e38f1c5df5f513205ea63f0de0e961564c 100644 (file)
@@ -205,24 +205,24 @@ void calc_image_view(SpaceImage *sima, char mode)
 
 void what_image(SpaceImage *sima)
 {
-       extern TFace *lasttface;        /* editface.c */
+       TFace *activetf;
        Mesh *me;
                
        if(sima->mode==SI_TEXTURE) {
                if(G.f & G_FACESELECT) {
 
                        sima->image= 0;
-                       me= get_mesh((G.scene->basact) ? (G.scene->basact->object) : 0);
-                       set_lasttface();
+                       me= get_mesh(OBACT);
+                       activetf = get_active_tface();
                        
-                       if(me && me->tface && lasttface && lasttface->mode & TF_TEX) {
-                               sima->image= lasttface->tpage;
+                       if(me && me->tface && activetf && activetf->mode & TF_TEX) {
+                               sima->image= activetf->tpage;
                                        
                                if(sima->flag & SI_EDITTILE);
-                               else sima->curtile= lasttface->tile;
+                               else sima->curtile= activetf->tile;
                                
                                if(sima->image) {
-                                       if(lasttface->mode & TF_TILES)
+                                       if(activetf->mode & TF_TILES)
                                                sima->image->tpageflag |= IMA_TILES;
                                        else sima->image->tpageflag &= ~IMA_TILES;
                                }
index acf81405547aa19d0bbbdfd1c85b5c676485c8da..ec69eecd8d0e449f93fc863bdfeb1f1498bb3a83 100644 (file)
@@ -515,7 +515,8 @@ static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flag
        flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
        *flags_p |= flags;
 }
-static EdgeHash *get_marked_edge_info(Mesh *me)
+
+EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
 {
        EdgeHash *eh = BLI_edgehash_new();
        int i;
@@ -618,20 +619,25 @@ static int draw_tfaces3D__setActiveOpts(void *userData, int index)
                return 0;
        }
 }
-static int draw_tfaces3D__drawFaceOpts(TFace *tface, int matnr)
+static int draw_tfaces3D__drawFaceOpts(void *userData, int index, int matnr)
 {
-       if (tface && !(tface->flag&TF_HIDE) && (tface->flag&TF_SELECT)) {
-               return 2; /* Don't set color */
-       } else {
+       Mesh *me = (Mesh*)userData;
+
+       if (me->tface) {
+               TFace *tface = &me->tface[index];
+               if (!(tface->flag&TF_HIDE) && (tface->flag&TF_SELECT))
+                       return 2; /* Don't set color */
+               else
+                       return 0;
+       } else
                return 0;
-       }
 }
 static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
 {
        struct { Mesh *me; EdgeHash *eh; } data;
 
        data.me = me;
-       data.eh = get_marked_edge_info(me);
+       data.eh = get_tface_mesh_marked_edge_info(me);
 
        glEnable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
@@ -657,7 +663,7 @@ static void draw_tfaces3D(Object *ob, Mesh *me, DerivedMesh *dm)
                glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                BIF_ThemeColor4(TH_FACE_SELECT);
 
-               dm->drawFacesTex(dm, draw_tfaces3D__drawFaceOpts);
+               dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me);
 
                glDisable(GL_BLEND);
        }
@@ -838,8 +844,11 @@ static Object *g_draw_tface_mesh_ob = NULL;
 static int g_draw_tface_mesh_islight = 0;
 static int g_draw_tface_mesh_istex = 0;
 static unsigned char g_draw_tface_mesh_obcol[4];
-static int draw_tface_mesh__set_draw(TFace *tface, int matnr)
+static int draw_tface_mesh__set_draw(void *userData, int index, int matnr)
 {
+       Mesh *me = (Mesh*)userData;
+       TFace *tface = (me->tface)? &me->tface[index]: NULL;
+
        if (tface && ((tface->flag&TF_HIDE) || (tface->mode&TF_INVISIBLE))) return 0;
 
        if (set_draw_settings_cached(0, g_draw_tface_mesh_istex, tface, g_draw_tface_mesh_islight, g_draw_tface_mesh_ob, matnr, TF_TWOSIDE)) {
@@ -901,7 +910,7 @@ void draw_tface_mesh(Object *ob, Mesh *me, int dt)
                int editing= (G.f & (G_VERTEXPAINT+G_FACESELECT+G_TEXTUREPAINT+G_WEIGHTPAINT)) && (ob==((G.scene->basact) ? (G.scene->basact->object) : 0));
                int start, totface;
 
-               dm->drawFacesTex(dm, draw_tface_mesh__set_draw);
+               dm->drawMappedFacesTex(dm, draw_tface_mesh__set_draw, (void*)me);
 
                start = 0;
                totface = me->totface;
index 14e9b46df877fe3d0605385278f3b7d8c74130c7..d4e5d102f7c31a7ae8cdbb216e44c0cc8f93b93b 100644 (file)
@@ -71,6 +71,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
 #include "BLI_editVert.h"
+#include "BLI_edgehash.h"
 
 #include "BKE_utildefines.h"
 #include "BKE_curve.h"
@@ -4110,17 +4111,47 @@ static int bbs_mesh_solid__setDrawOpts(void *userData, int index, int *drawSmoot
                return 0;
        }
 }
+
+static int bbs_mesh_wire__setDrawOpts(void *userData, int index)
+{
+       struct { Mesh *me; EdgeHash *eh; int offset; } *data = userData;
+       MEdge *med = data->me->medge + index;
+       unsigned int flags = (int)BLI_edgehash_lookup(data->eh, med->v1, med->v2);
+
+       if (flags & 1) {
+               set_framebuffer_index_color(data->offset+index);
+               return 1;
+       } else
+               return 0;
+}
+
 static void bbs_mesh_solid(Object *ob)
 {
        int dmNeedsFree;
        DerivedMesh *dm = mesh_get_derived_final(ob, &dmNeedsFree);
+       Mesh *me = (Mesh*)ob->data;
        
        glColor3ub(0, 0, 0);
-       dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, ob->data, 0);
-       
-       if (dmNeedsFree) {
-               dm->release(dm);
+       dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, me, 0);
+
+       /* draw edges for seam marking in faceselect mode, but not when painting,
+          so that painting doesn't get interrupted on an edge */
+       if ((G.f & G_FACESELECT) && !(G.f & (G_VERTEXPAINT|G_TEXTUREPAINT|G_WEIGHTPAINT))) {
+               struct { Mesh *me; EdgeHash *eh; int offset; } userData;
+
+               userData.me = me;
+               userData.eh = get_tface_mesh_marked_edge_info(me);
+               userData.offset = userData.me->totface+1;
+
+               bglPolygonOffset(1.0);
+               dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOpts, (void*)&userData);
+               bglPolygonOffset(0.0);
+
+               BLI_edgehash_free(userData.eh, NULL);
        }
+
+       if (dmNeedsFree)
+               dm->release(dm);
 }
 
 void draw_object_backbufsel(Object *ob)
@@ -4145,7 +4176,7 @@ void draw_object_backbufsel(Object *ob)
                        
                        // we draw edges always, for loop (select) tools
                        em_wireoffs= bbs_mesh_wire(dm, em_solidoffs);
-                       
+
                        if(G.scene->selectmode & SCE_SELECT_VERTEX) 
                                em_vertoffs= bbs_mesh_verts(dm, em_wireoffs);
                        else em_vertoffs= em_wireoffs;
index 28001e2918d373fcdd1fe44df1452d803bd3f43a..26704d4d8765ea28c7840a2cafbb45fffde2831c 100644 (file)
@@ -49,6 +49,7 @@
 #include "BMF_Api.h"
 
 #include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
 
 #include "DNA_action_types.h"
 #include "DNA_armature_types.h"
@@ -1054,7 +1055,143 @@ void backdrawview3d(int test)
 
 }
 
+void check_backbuf(void)
+{
+       if(G.vd->flag & V3D_NEEDBACKBUFDRAW)
+               backdrawview3d(0);
+}
+
+/* samples a single pixel (copied from vpaint) */
+unsigned int sample_backbuf(int x, int y)
+{
+       unsigned int col;
+       
+       if(x>=curarea->winx || y>=curarea->winy) return 0;
+       x+= curarea->winrct.xmin;
+       y+= curarea->winrct.ymin;
+       
+       check_backbuf(); // actually not needed for apple
+
+#ifdef __APPLE__
+       glReadBuffer(GL_AUX0);
+#endif
+       glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
+       glReadBuffer(GL_BACK);  
+       
+       if(G.order==B_ENDIAN) SWITCH_INT(col);
+       
+       return framebuffer_to_index(col);
+}
+
+/* reads full rect, converts indices */
+ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
+{
+       unsigned int *dr, *rd;
+       struct ImBuf *ibuf, *ibuf1;
+       int a;
+       short xminc, yminc, xmaxc, ymaxc, xs, ys;
+       
+       /* clip */
+       if(xmin<0) xminc= 0; else xminc= xmin;
+       if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
+       if(xminc > xmaxc) return NULL;
+
+       if(ymin<0) yminc= 0; else yminc= ymin;
+       if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
+       if(yminc > ymaxc) return NULL;
+       
+       ibuf= IMB_allocImBuf((xmaxc-xminc+1),(ymaxc-yminc+1),32,IB_rect,0);
+
+       check_backbuf(); // actually not needed for apple
+       
+#ifdef __APPLE__
+       glReadBuffer(GL_AUX0);
+#endif
+       glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+       glReadBuffer(GL_BACK);  
+
+       if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
+
+       a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
+       dr= ibuf->rect;
+       while(a--) {
+               if(*dr) *dr= framebuffer_to_index(*dr);
+               dr++;
+       }
+       
+       /* put clipped result back, if needed */
+       if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf;
+       ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0);
+       rd= ibuf->rect;
+       dr= ibuf1->rect;
                
+       for(ys= ymin; ys<=ymax; ys++) {
+               for(xs= xmin; xs<=xmax; xs++, dr++) {
+                       if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
+                               *dr= *rd;
+                               rd++;
+                       }
+               }
+       }
+       IMB_freeImBuf(ibuf);
+       return ibuf1;
+}
+
+/* smart function to sample a rect spiralling outside, nice for backbuf selection */
+unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
+{
+       struct ImBuf *buf;
+       unsigned int *bufmin, *bufmax, *tbuf;
+       int minx, miny;
+       int a, b, rc, nr, amount, dirvec[4][2];
+       short distance=0;
+       unsigned int index = 0;
+       
+       amount= (size-1)/2;
+
+       minx = mval[0]-(amount+1);
+       miny = mval[1]-(amount+1);
+       buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
+       if (!buf) return 0;
+
+       rc= 0;
+       
+       dirvec[0][0]= 1; dirvec[0][1]= 0;
+       dirvec[1][0]= 0; dirvec[1][1]= -size;
+       dirvec[2][0]= -1; dirvec[2][1]= 0;
+       dirvec[3][0]= 0; dirvec[3][1]= size;
+       
+       bufmin = buf->rect;
+       tbuf = buf->rect;
+       bufmax = buf->rect + size*size;
+       tbuf+= amount*size+ amount;
+       
+       for(nr=1; nr<=size; nr++) {
+               
+               for(a=0; a<2; a++) {
+                       for(b=0; b<nr; b++, distance++) {
+                               if (*tbuf && *tbuf>=min && *tbuf<max) {
+                                       *dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
+                                       index = *tbuf - min+1; // messy yah, but indices start at 1
+                                       goto exit;
+                               }
+                               
+                               tbuf+= (dirvec[rc][0]+dirvec[rc][1]);
+                               
+                               if(tbuf<bufmin || tbuf>=bufmax) {
+                                       goto exit;
+                               }
+                       }
+                       rc++;
+                       rc &= 3;
+               }
+       }
+
+exit:
+       IMB_freeImBuf(buf);
+       return index;
+}
+
 void drawname(Object *ob)
 {
        cpack(0x404040);
index d1812bba205940e2b1d8162e2765dd0a5259bc81..e6b64a276c1549f23f9fb30bdfd4ce34b2667bc6 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
+#include "BLI_heap.h"
+#include "BLI_edgehash.h"
 
 #include "MTC_matrixops.h"
 
 
 #include "BDR_unwrapper.h"
 
-TFace *lasttface=NULL;
+/* returns 0 if not found, otherwise 1 */
+static int facesel_face_pick(Mesh *me, short *mval, unsigned int *index, short rect)
+{
+       if (!me->tface || me->totface==0)
+               return 0;
+
+       if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
+               check_backbuf();
+               persp(PERSP_VIEW);
+       }
+
+       if (rect) {
+               /* sample rect to increase changes of selecting, so that when clicking
+                  on an edge in the backbuf, we can still select a face */
+               short dist;
+               *index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist);
+       }
+       else
+               /* sample only on the exact position */
+               *index = sample_backbuf(mval[0], mval[1]);
+
+       if ((*index)<=0 || (*index)>(unsigned int)me->totface)
+               return 0;
+
+       (*index)--;
+       
+       return 1;
+}
+
+/* returns 0 if not found, otherwise 1 */
+static int facesel_edge_pick(Mesh *me, short *mval, unsigned int *index)
+{
+       short dist;
+       unsigned int min = me->totface + 1;
+       unsigned int max = me->totface + me->totedge + 1;
+
+       if (me->totedge == 0)
+               return 0;
+
+       if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
+               check_backbuf();
+               persp(PERSP_VIEW);
+       }
+
+       *index = sample_backbuf_rect(mval, 50, min, max, &dist);
+
+       if (*index == 0)
+               return 0;
+
+       (*index)--;
+       
+       return 1;
+}
 
 static void uv_calc_center_vector(float *result, Object *ob, Mesh *me)
 {
@@ -487,47 +541,32 @@ void calculate_uv_map(unsigned short mapmode)
        allqueue(REDRAWIMAGE, 0);
 }
 
-void set_lasttface()
+TFace *get_active_tface()
 {
        Mesh *me;
-       TFace *tface;
+       TFace *tf;
        int a;
        
-       lasttface= 0;
-       if(OBACT==NULL || OBACT->type!=OB_MESH) return;
+       if(OBACT==NULL || OBACT->type!=OB_MESH)
+               return NULL;
        
        me= get_mesh(OBACT);
-       if(me==0 || me->tface==0) return;
+       if(me==0 || me->tface==0)
+               return NULL;
        
-       tface= me->tface;
-       a= me->totface;
-       while(a--) {
-               if(tface->flag & TF_ACTIVE) {
-                       lasttface= tface;
-                       return;
-               }
-               tface++;
-       }
+       for(a=0, tf=me->tface; a < me->totface; a++, tf++)
+               if(tf->flag & TF_ACTIVE)
+                       return tf;
 
-       tface= me->tface;
-       a= me->totface;
-       while(a--) {
-               if(tface->flag & TF_SELECT) {
-                       lasttface= tface;
-                       return;
-               }
-               tface++;
-       }
+       for(a=0, tf=me->tface; a < me->totface; a++, tf++)
+               if(tf->flag & TF_SELECT)
+                       return tf;
 
-       tface= me->tface;
-       a= me->totface;
-       while(a--) {
-               if((tface->flag & TF_HIDE)==0) {
-                       lasttface= tface;
-                       return;
-               }
-               tface++;
-       }
+       for(a=0, tf=me->tface; a < me->totface; a++, tf++)
+               if((tf->flag & TF_HIDE)==0)
+                       return tf;
+       
+       return NULL;
 }
 
 void default_uv(float uv[][2], float size)
@@ -660,7 +699,7 @@ void select_linked_tfaces(int mode)
                        error("The active object is not in this layer");
                        
                getmouseco_areawin(mval);
-               if (!face_pick(me, mval[0], mval[1], &index)) return;
+               if (!facesel_face_pick(me, mval, &index, 1)) return;
        }
 
        select_linked_tfaces_with_seams(mode, me, index);
@@ -910,55 +949,275 @@ void minmax_tface(float *min, float *max)
        }
 }
 
-/**
- * Returns the face under the give position in screen coordinates.
- * Code extracted from face_select routine.
- * Question: why is all of the backbuffer drawn?
- * We're only interested in one pixel!
- * @author     Maarten Gribnau
- * @param      me              the mesh with the faces to be picked
- * @param      x               the x-coordinate to pick at
- * @param      y               the y-coordinate to pick at
- * @param      index   the index of the face
- * @return 1 if found, 0 if none found
- */
-int face_pick(Mesh *me, short x, short y, unsigned int *index)
+#define ME_SEAM_DONE ME_SEAM_LAST              /* reuse this flag */
+
+static float seam_cut_cost(Mesh *me, int e1, int e2, int vert)
 {
-       unsigned int col;
+       MVert *v = me->mvert + vert;
+       MEdge *med1 = me->medge + e1, *med2 = me->medge + e2;
+       MVert *v1 = me->mvert + ((med1->v1 == vert)? med1->v2: med1->v1);
+       MVert *v2 = me->mvert + ((med2->v1 == vert)? med2->v2: med2->v1);
+       float cost, d1[3], d2[3];
 
-       if (me==0 || me->tface==0)
-               return 0;
+       cost = VecLenf(v1->co, v->co);
+       cost += VecLenf(v->co, v2->co);
+
+       VecSubf(d1, v->co, v1->co);
+       VecSubf(d2, v2->co, v->co);
+
+       cost = cost + 0.5f*cost*(2.0f - fabs(d1[0]*d2[0] + d1[1]*d2[1] + d1[2]*d2[2]));
 
-       /* Have OpenGL draw in the back buffer with color coded face indices */
-       if (curarea->win_swap==WIN_EQUAL) {
-               G.vd->flag |= V3D_NEEDBACKBUFDRAW;
+       return cost;
+}
+
+static void seam_add_adjacent(Mesh *me, Heap *heap, int mednum, int vertnum, int *nedges, int *edges, int *prevedge, float *cost)
+{
+       int startadj, endadj = nedges[vertnum+1];
+
+       for (startadj = nedges[vertnum]; startadj < endadj; startadj++) {
+               int adjnum = edges[startadj];
+               MEdge *medadj = me->medge + adjnum;
+               float newcost;
+
+               if (medadj->flag & ME_SEAM_DONE)
+                       continue;
+
+               newcost = cost[mednum] + seam_cut_cost(me, mednum, adjnum, vertnum);
+
+               if (cost[adjnum] > newcost) {
+                       cost[adjnum] = newcost;
+                       prevedge[adjnum] = mednum;
+                       BLI_heap_insert(heap, newcost, (void*)adjnum);
+               }
        }
-       if (G.vd->flag & V3D_NEEDBACKBUFDRAW) {
-               backdrawview3d(0);
-               persp(PERSP_VIEW);
+}
+
+static int seam_shortest_path(Mesh *me, int source, int target)
+{
+       Heap *heap;
+       EdgeHash *ehash;
+       float *cost;
+       MEdge *med;
+       int a, *nedges, *edges, *prevedge, mednum = -1, nedgeswap = 0;
+       TFace *tf;
+       MFace *mf;
+
+       /* mark hidden edges as done, so we don't use them */
+       ehash = BLI_edgehash_new();
+
+       for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++) {
+               if (!(tf->flag & TF_HIDE)) {
+                       BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
+                       BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
+                       if (mf->v4) {
+                               BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
+                               BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
+                       }
+                       else
+                               BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
+               }
        }
-       /* Read the pixel under the cursor */
-#ifdef __APPLE__
-       glReadBuffer(GL_AUX0);
-#endif
-       glReadPixels(x+curarea->winrct.xmin, y+curarea->winrct.ymin, 1, 1,
-               GL_RGBA, GL_UNSIGNED_BYTE, &col);
-       glReadBuffer(GL_BACK);
 
-       /* Unbelievable! */
-       if (G.order==B_ENDIAN) {
-               SWITCH_INT(col);
+       for (a=0, med=me->medge; a<me->totedge; a++, med++)
+               if (!BLI_edgehash_haskey(ehash, med->v1, med->v2))
+                       med->flag |= ME_SEAM_DONE;
+
+       BLI_edgehash_free(ehash, NULL);
+
+       /* alloc */
+       nedges = MEM_callocN(sizeof(*nedges)*me->totvert+1, "SeamPathNEdges");
+       edges = MEM_mallocN(sizeof(*edges)*me->totedge*2, "SeamPathEdges");
+       prevedge = MEM_mallocN(sizeof(*prevedge)*me->totedge, "SeamPathPrevious");
+       cost = MEM_mallocN(sizeof(*cost)*me->totedge, "SeamPathCost");
+
+       /* count edges, compute adjacent edges offsets and fill adjacent edges */
+       for (a=0, med=me->medge; a<me->totedge; a++, med++) {
+               nedges[med->v1+1]++;
+               nedges[med->v2+1]++;
        }
-       /* Convert the color back to a face index */
-       *index = framebuffer_to_index(col);
-       if (col==0 || (*index)<=0 || (*index)>(unsigned) me->totface)
-               return 0;
 
-       (*index)--;
+       for (a=1; a<me->totvert; a++) {
+               int newswap = nedges[a+1];
+               nedges[a+1] = nedgeswap + nedges[a];
+               nedgeswap = newswap;
+       }
+       nedges[0] = nedges[1] = 0;
+
+       for (a=0, med=me->medge; a<me->totedge; a++, med++) {
+               edges[nedges[med->v1+1]++] = a;
+               edges[nedges[med->v2+1]++] = a;
+
+               cost[a] = 1e20f;
+               prevedge[a] = -1;
+       }
+
+       /* regular dijkstra shortest path, but over edges instead of vertices */
+       heap = BLI_heap_new();
+       BLI_heap_insert(heap, 0.0f, (void*)source);
+       cost[source] = 0.0f;
+
+       while (!BLI_heap_empty(heap)) {
+               mednum = (int)BLI_heap_popmin(heap);
+               med = me->medge + mednum;
+
+               if (mednum == target)
+                       break;
+
+               if (med->flag & ME_SEAM_DONE)
+                       continue;
+
+               med->flag |= ME_SEAM_DONE;
+
+               seam_add_adjacent(me, heap, mednum, med->v1, nedges, edges, prevedge, cost);
+               seam_add_adjacent(me, heap, mednum, med->v2, nedges, edges, prevedge, cost);
+       }
        
+       MEM_freeN(nedges);
+       MEM_freeN(edges);
+       MEM_freeN(cost);
+       BLI_heap_free(heap, NULL);
+
+       for (a=0, med=me->medge; a<me->totedge; a++, med++)
+               med->flag &= ~ME_SEAM_DONE;
+
+       if (mednum != target) {
+               MEM_freeN(prevedge);
+               return 0;
+       }
+
+       /* follow path back to source and mark as seam */
+       if (mednum == target) {
+               short allseams = 1;
+
+               mednum = target;
+               do {
+                       med = me->medge + mednum;
+                       if (!(med->flag & ME_SEAM)) {
+                               allseams = 0;
+                               break;
+                       }
+                       mednum = prevedge[mednum];
+               } while (mednum != source);
+
+               mednum = target;
+               do {
+                       med = me->medge + mednum;
+                       if (allseams)
+                               med->flag &= ~ME_SEAM;
+                       else
+                               med->flag |= ME_SEAM;
+                       mednum = prevedge[mednum];
+               } while (mednum != -1);
+       }
+
+       MEM_freeN(prevedge);
        return 1;
 }
 
+static void seam_select(Mesh *me, short *mval, short path)
+{
+       unsigned int index = 0;
+       MEdge *medge, *med;
+       int a, lastindex = -1;
+
+       if (!facesel_edge_pick(me, mval, &index))
+               return;
+
+       for (a=0, med=me->medge; a<me->totedge; a++, med++) {
+               if (med->flag & ME_SEAM_LAST) {
+                       lastindex = a;
+                       med->flag &= ~ME_SEAM_LAST;
+                       break;
+               }
+       }
+
+       medge = me->medge + index;
+       if (!path || (lastindex == -1) || (index == lastindex) ||
+           !seam_shortest_path(me, lastindex, index))
+               medge->flag ^= ME_SEAM;
+       medge->flag |= ME_SEAM_LAST;
+
+       G.f |= G_DRAWSEAMS;
+
+       if (G.rt == 8)
+               unwrap_lscm(1);
+
+       BIF_undo_push("Mark Seam");
+
+       object_tface_flags_changed(OBACT, 1);
+}
+
+void seam_edgehash_insert_face(EdgeHash *ehash, MFace *mf)
+{
+       BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
+       BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
+       if (mf->v4) {
+               BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
+               BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
+       }
+       else
+               BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
+}
+
+void seam_mark_clear_tface(short mode)
+{
+       Mesh *me;
+       TFace *tf;
+       MFace *mf;
+       MEdge *med;
+       int a;
+       
+       me= get_mesh(OBACT);
+       if(me==0 || me->tface==0 || me->totface==0) return;
+
+       if (mode == 0)
+               mode = pupmenu("Seams%t|Mark Border Seam %x1|Clear Seam %x2");
+
+       if (mode != 1 && mode != 2)
+               return;
+
+       if (mode == 2) {
+               EdgeHash *ehash = BLI_edgehash_new();
+
+               for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++)
+                       if (!(tf->flag & TF_HIDE) && (tf->flag & TF_SELECT))
+                               seam_edgehash_insert_face(ehash, mf);
+
+               for (a=0, med=me->medge; a<me->totedge; a++, med++)
+                       if (BLI_edgehash_haskey(ehash, med->v1, med->v2))
+                               med->flag &= ~ME_SEAM;
+
+               BLI_edgehash_free(ehash, NULL);
+       }
+       else {
+               /* mark edges that are on both selected and deselected faces */
+               EdgeHash *ehash1 = BLI_edgehash_new();
+               EdgeHash *ehash2 = BLI_edgehash_new();
+
+               for (a=0, mf=me->mface, tf=me->tface; a<me->totface; a++, tf++, mf++) {
+                       if ((tf->flag & TF_HIDE) || !(tf->flag & TF_SELECT))
+                               seam_edgehash_insert_face(ehash1, mf);
+                       else
+                               seam_edgehash_insert_face(ehash2, mf);
+               }
+
+               for (a=0, med=me->medge; a<me->totedge; a++, med++)
+                       if (BLI_edgehash_haskey(ehash1, med->v1, med->v2) &&
+                           BLI_edgehash_haskey(ehash2, med->v1, med->v2))
+                               med->flag |= ME_SEAM;
+
+               BLI_edgehash_free(ehash1, NULL);
+               BLI_edgehash_free(ehash2, NULL);
+       }
+
+       if (G.rt == 8)
+               unwrap_lscm(1);
+
+       BIF_undo_push("Mark Seam");
+
+       object_tface_flags_changed(OBACT, 1);
+}
+
 void face_select()
 {
        Object *ob;
@@ -975,7 +1234,13 @@ void face_select()
        }
        me = get_mesh(ob);
        getmouseco_areawin(mval);
-       if (!face_pick(me, mval[0], mval[1], &index)) return;
+
+       if (G.qual & LR_ALTKEY) {
+               seam_select(me, mval, (G.qual & LR_SHIFTKEY) != 0);
+               return;
+       }
+
+       if (!facesel_face_pick(me, mval, &index, 1)) return;
        
        tsel= (((TFace*)me->tface)+index);
        msel= (((MFace*)me->mface)+index);
@@ -1003,8 +1268,6 @@ void face_select()
        }
        else tsel->flag |= TF_SELECT;
        
-       lasttface = tsel;
-       
        /* image window redraw */
        
        BIF_undo_push("Select UV face");
@@ -1149,7 +1412,7 @@ void uv_autocalc_tface()
        case UV_WINDOW_MAPPING:
                calculate_uv_map(B_UVAUTO_WINDOW); break;
        case UV_UNWRAP_MAPPING:
-               unwrap_lscm(); break;
+               unwrap_lscm(0); break;
        }
 }
 
@@ -1176,10 +1439,6 @@ void set_faceselect()    /* toggle */
 
        if(G.f & G_FACESELECT) {
                setcursor_space(SPACE_VIEW3D, CURSOR_FACESEL);
-               if(me) {
-                       set_lasttface();
-                       set_seamtface(); /* set TF_SEAM flags in tface */
-               }
                BIF_undo_push("Set UV Faceselect");
        }
        else if((G.f & (G_WEIGHTPAINT|G_VERTEXPAINT|G_TEXTUREPAINT))==0) {
@@ -1497,7 +1756,7 @@ void face_draw()
                if ((xy[0] != xy_old[0]) || (xy[1] != xy_old[1])) {
 
                        /* Get face to draw on */
-                       if (!face_pick(me, xy[0], xy[1], &face_index)) face = NULL;
+                       if (!facesel_face_pick(me, xy, &face_index, 0)) face = NULL;
                        else face = (((TFace*)me->tface)+face_index);
 
                        /* Check if this is another face. */
index 8c8315f23fa0004ab3cd37f8177123f5e6309825..aa3353046a8b39eabcf3f754536ba8bbd94f5005 100644 (file)
@@ -123,145 +123,6 @@ void EM_select_mirrored(void)
 
 unsigned int em_solidoffs=0, em_wireoffs=0, em_vertoffs=0;     // set in drawobject.c ... for colorindices
 
-static void check_backbuf(void)
-{
-       if(G.vd->flag & V3D_NEEDBACKBUFDRAW) {
-               backdrawview3d(0);
-       }
-}
-
-/* samples a single pixel (copied from vpaint) */
-static unsigned int sample_backbuf(int x, int y)
-{
-       unsigned int col;
-       
-       if(x>=curarea->winx || y>=curarea->winy) return 0;
-       x+= curarea->winrct.xmin;
-       y+= curarea->winrct.ymin;
-       
-       check_backbuf(); // actually not needed for apple
-
-#ifdef __APPLE__
-       glReadBuffer(GL_AUX0);
-#endif
-       glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
-       glReadBuffer(GL_BACK);  
-       
-       if(G.order==B_ENDIAN) SWITCH_INT(col);
-       
-       return framebuffer_to_index(col);
-}
-
-/* reads full rect, converts indices */
-struct ImBuf *read_backbuf(short xmin, short ymin, short xmax, short ymax)
-{
-       unsigned int *dr, *rd;
-       struct ImBuf *ibuf, *ibuf1;
-       int a;
-       short xminc, yminc, xmaxc, ymaxc, xs, ys;
-       
-       /* clip */
-       if(xmin<0) xminc= 0; else xminc= xmin;
-       if(xmax>=curarea->winx) xmaxc= curarea->winx-1; else xmaxc= xmax;
-       if(xminc > xmaxc) return NULL;
-
-       if(ymin<0) yminc= 0; else yminc= ymin;
-       if(ymax>=curarea->winy) ymaxc= curarea->winy-1; else ymaxc= ymax;
-       if(yminc > ymaxc) return NULL;
-       
-       ibuf= IMB_allocImBuf((xmaxc-xminc+1),(ymaxc-yminc+1),32,IB_rect,0);
-
-       check_backbuf(); // actually not needed for apple
-       
-#ifdef __APPLE__
-       glReadBuffer(GL_AUX0);
-#endif
-       glReadPixels(curarea->winrct.xmin+xminc, curarea->winrct.ymin+yminc, (xmaxc-xminc+1), (ymaxc-yminc+1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
-       glReadBuffer(GL_BACK);  
-
-       if(G.order==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
-
-       a= (xmaxc-xminc+1)*(ymaxc-yminc+1);
-       dr= ibuf->rect;
-       while(a--) {
-               if(*dr) *dr= framebuffer_to_index(*dr);
-               dr++;
-       }
-       
-       /* put clipped result back, if needed */
-       if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf;
-       ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0);
-       rd= ibuf->rect;
-       dr= ibuf1->rect;
-               
-       for(ys= ymin; ys<=ymax; ys++) {
-               for(xs= xmin; xs<=xmax; xs++, dr++) {
-                       if( xs>=xminc && xs<=xmaxc && ys>=yminc && ys<=ymaxc) {
-                               *dr= *rd;
-                               rd++;
-                       }
-               }
-       }
-       IMB_freeImBuf(ibuf);
-       return ibuf1;
-}
-
-
-/* smart function to sample a rect spiralling outside, nice for backbuf selection */
-static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
-{
-       struct ImBuf *buf;
-       unsigned int *bufmin, *bufmax, *tbuf;
-       int minx, miny;
-       int a, b, rc, nr, amount, dirvec[4][2];
-       short distance=0;
-       unsigned int index = 0;
-       
-       amount= (size-1)/2;
-
-       minx = mval[0]-(amount+1);
-       miny = mval[1]-(amount+1);
-       buf = read_backbuf(minx, miny, minx+size-1, miny+size-1);
-       if (!buf) return 0;
-
-       rc= 0;
-       
-       dirvec[0][0]= 1; dirvec[0][1]= 0;
-       dirvec[1][0]= 0; dirvec[1][1]= -size;
-       dirvec[2][0]= -1; dirvec[2][1]= 0;
-       dirvec[3][0]= 0; dirvec[3][1]= size;
-       
-       bufmin = buf->rect;
-       tbuf = buf->rect;
-       bufmax = buf->rect + size*size;
-       tbuf+= amount*size+ amount;
-       
-       for(nr=1; nr<=size; nr++) {
-               
-               for(a=0; a<2; a++) {
-                       for(b=0; b<nr; b++, distance++) {
-                               if (*tbuf && *tbuf>=min && *tbuf<max) {
-                                       *dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
-                                       index = *tbuf - min+1; // messy yah, but indices start at 1
-                                       goto exit;
-                               }
-                               
-                               tbuf+= (dirvec[rc][0]+dirvec[rc][1]);
-                               
-                               if(tbuf<bufmin || tbuf>=bufmax) {
-                                       goto exit;
-                               }
-                       }
-                       rc++;
-                       rc &= 3;
-               }
-       }
-
-exit:
-       IMB_freeImBuf(buf);
-       return index;
-}
-
 /* facilities for border select and circle select */
 static char *selbuf= NULL;
 
index 40a83d03a94cfa10ad7f721a2a390cedddee77f6..a54ac6106fef4c25007ea6748a1595bb16c5c896 100644 (file)
@@ -1504,10 +1504,8 @@ void exit_editmode(int freedata) /* freedata==0 at render, 1= freedata, 2= do un
 
                if(freedata) free_editMesh(G.editMesh);
 
-               if(G.f & G_FACESELECT) {
-                       set_seamtface();
+               if(G.f & G_FACESELECT)
                        allqueue(REDRAWIMAGE, 0);
-               }
                if(G.f & G_WEIGHTPAINT)
                        mesh_octree_table(G.obedit, NULL, 'e');
        }
index 998839844c52903dc145bf60b99964f47f41cb01..61456fb0c38c18060d4eaec007c558168d6f1439 100644 (file)
@@ -1029,7 +1029,7 @@ static void do_image_uvsmenu(void *arg, int event)
                pin_tface_uv(0);
                break;
     case 10:
-               unwrap_lscm();
+               unwrap_lscm(0);
                break;
        case 11:
                if(G.sima->flag & SI_LIVE_UNWRAP) G.sima->flag &= ~SI_LIVE_UNWRAP;
@@ -1072,7 +1072,7 @@ static uiBlock *image_uvsmenu(void *arg_unused)
 
        uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");        
 
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Minimize Stretch|Ctrl V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Limit Stitch...|Shift V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Stitch|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
        uiDefIconTextBlockBut(block, image_uvs_transformmenu, NULL, ICON_RIGHTARROW_THIN, "Transform", 0, yco-=20, 120, 19, "");
index e8598bd265f6930deb2e3ba6d686f6df81964ebc..6ffd2bd68a18215e28845748fce4f123098de78a 100644 (file)
@@ -3574,55 +3574,56 @@ static uiBlock *view3d_paintmenu(void *arg_unused)
 
 static void do_view3d_facesel_propertiesmenu(void *arg, int event)
 {
-       extern TFace *lasttface;
-       set_lasttface();
-       
-       switch(event) {
-       case 0: /*      textured */
-               lasttface->mode ^= TF_TEX;
-               break;
-       case 1: /* tiled*/
-               lasttface->mode ^= TF_TILES;
-               break;
-       case 2: /* light */
-               lasttface->mode ^= TF_LIGHT;
-               break;
-       case 3: /* invisible */
-               lasttface->mode ^= TF_INVISIBLE;
-               break;
-       case 4: /* collision */
-               lasttface->mode ^= TF_DYNAMIC;
-               break;
-       case 5: /* shared vertex colors */
-               lasttface->mode ^= TF_SHAREDCOL;
-               break;
-       case 6: /* two sided */
-               lasttface->mode ^= TF_TWOSIDE;
-               break;
-       case 7: /* use object color */
-               lasttface->mode ^= TF_OBCOL;
-               break;
-       case 8: /* halo */
-               lasttface->mode ^= TF_BILLBOARD;
-               break;
-       case 9: /* billboard */
-               lasttface->mode ^= TF_BILLBOARD2;
-               break;
-       case 10: /* shadow */
-               lasttface->mode ^= TF_SHADOW;
-               break;
-       case 11: /* text */
-               lasttface->mode ^= TF_BMFONT;
-               break;
-       case 12: /* opaque blend mode */
-               lasttface->transp = TF_SOLID;
-               break;
-       case 13: /* additive blend mode */
-               lasttface->transp |= TF_ADD;
-               break;
-       case 14: /* alpha blend mode */
-               lasttface->transp = TF_ALPHA;
-               break;
+       TFace *tf = get_active_tface();
+
+       if (tf) {
+               switch(event) {
+               case 0: /*      textured */
+                       tf->mode ^= TF_TEX;
+                       break;
+               case 1: /* tiled*/
+                       tf->mode ^= TF_TILES;
+                       break;
+               case 2: /* light */
+                       tf->mode ^= TF_LIGHT;
+                       break;
+               case 3: /* invisible */
+                       tf->mode ^= TF_INVISIBLE;
+                       break;
+               case 4: /* collision */
+                       tf->mode ^= TF_DYNAMIC;
+                       break;
+               case 5: /* shared vertex colors */
+                       tf->mode ^= TF_SHAREDCOL;
+                       break;
+               case 6: /* two sided */
+                       tf->mode ^= TF_TWOSIDE;
+                       break;
+               case 7: /* use object color */
+                       tf->mode ^= TF_OBCOL;
+                       break;
+               case 8: /* halo */
+                       tf->mode ^= TF_BILLBOARD;
+                       break;
+               case 9: /* billboard */
+                       tf->mode ^= TF_BILLBOARD2;
+                       break;
+               case 10: /* shadow */
+                       tf->mode ^= TF_SHADOW;
+                       break;
+               case 11: /* text */
+                       tf->mode ^= TF_BMFONT;
+                       break;
+               case 12: /* opaque blend mode */
+                       tf->transp = TF_SOLID;
+                       break;
+               case 13: /* additive blend mode */
+                       tf->transp |= TF_ADD;
+                       break;
+               case 14: /* alpha blend mode */
+                       tf->transp = TF_ALPHA;
+                       break;
+               }
        }
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWBUTSEDIT, 0);
@@ -3630,61 +3631,60 @@ static void do_view3d_facesel_propertiesmenu(void *arg, int event)
 
 static uiBlock *view3d_facesel_propertiesmenu(void *arg_unused)
 {
-       extern TFace *lasttface;
+       TFace *tf = get_active_tface();
        uiBlock *block;
        short yco = 20, menuwidth = 120;
 
-       /* to display ticks/crosses depending on face properties */
-       set_lasttface();
+       /* display ticks/crosses depending on active tface properties */
 
        block= uiNewBlock(&curarea->uiblocks, "view3d_facesel_propertiesmenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
        uiBlockSetButmFunc(block, do_view3d_facesel_propertiesmenu, NULL);
        
-       if (lasttface->mode & TF_TEX) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Textured",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
+       if (tf->mode & TF_TEX) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Textured",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Textured",                                          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
        
-       if (lasttface->mode & TF_TILES) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Tiled",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+       if (tf->mode & TF_TILES) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Tiled",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Tiled",                                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
        
-       if (lasttface->mode & TF_LIGHT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Light",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+       if (tf->mode & TF_LIGHT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Light",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Light",                                             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
        
-       if (lasttface->mode & TF_INVISIBLE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Invisible",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+       if (tf->mode & TF_INVISIBLE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Invisible",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Invisible",                                         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
        
-       if (lasttface->mode & TF_DYNAMIC) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Collision",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
+       if (tf->mode & TF_DYNAMIC) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Collision",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Collision",                                         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 4, "");
        
-       if (lasttface->mode & TF_SHAREDCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shared Vertex Colors",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
+       if (tf->mode & TF_SHAREDCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shared Vertex Colors",                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Shared Vertex Colors",                                              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 5, "");
        
-       if (lasttface->mode & TF_TWOSIDE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Two Sided",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
+       if (tf->mode & TF_TWOSIDE) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Two Sided",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Two Sided",                                         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
        
-       if (lasttface->mode & TF_OBCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Object Color",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
+       if (tf->mode & TF_OBCOL) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Use Object Color",                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Use Object Color",                                          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 7, "");
        
-       if (lasttface->mode & TF_BILLBOARD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Halo",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
+       if (tf->mode & TF_BILLBOARD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Halo",                        0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Halo",                                              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
        
-       if (lasttface->mode & TF_BILLBOARD2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Billboard",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
+       if (tf->mode & TF_BILLBOARD2) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Billboard",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Billboard",                                         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
                
-       if (lasttface->mode & TF_SHADOW) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shadow",                  0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
+       if (tf->mode & TF_SHADOW) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Shadow",                 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Shadow",                                            0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 10, "");
        
-       if (lasttface->mode & TF_BMFONT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Text",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
+       if (tf->mode & TF_BMFONT) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Text",                   0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Text",                                              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 11, "");
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
-       if (lasttface->transp == TF_SOLID) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Opaque Blend Mode",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
+       if (tf->transp == TF_SOLID) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Opaque Blend Mode",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Opaque Blend Mode",                                         0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 12, "");
        
-       if (lasttface->transp == TF_ADD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Additive Blend Mode",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
+       if (tf->transp == TF_ADD) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Additive Blend Mode",                    0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Additive Blend Mode",                                               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 13, "");
        
-       if (lasttface->transp == TF_ALPHA) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Alpha Blend Mode",                      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
+       if (tf->transp == TF_ALPHA) uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Alpha Blend Mode",                     0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
        else uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Alpha Blend Mode",                                          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 14, "");
 
        uiBlockSetDirection(block, UI_RIGHT);
@@ -3731,44 +3731,36 @@ static void do_view3d_faceselmenu(void *arg, int event)
 {
        /* code copied from buttons.c :(        
                would be nice if it was split up into functions */
-       Mesh *me=NULL;
-       Object *ob=NULL;
-       extern TFace *lasttface; /* caches info on tface bookkeeping ?*/
-       TFace *tface;
+       Mesh *me;
+       TFace *tf, *activetf;
        int a;
        
        switch(event) {
        case 0: /* copy draw mode */
        case 1: /* copy UVs */
        case 2: /* copy vertex colors */
-               ob= OBACT;
-               if(ob==0) return;
-               me= get_mesh(ob);
-               if(!(me && me->tface)) return;
-
-               tface= me->tface;
-               a= me->totface;
-               set_lasttface();
-               if(lasttface) {
-               
-                       while(a--) {
-                               if(tface!=lasttface && (tface->flag & TF_SELECT)) {
+               me= get_mesh(OBACT);
+               activetf = get_active_tface();
+
+               if (me && activetf) {
+                       for (a=0, tf=me->tface; a < me->totface; a++, tf++) {
+                               if(tf!=activetf && (tf->flag & TF_SELECT)) {
                                        if(event==0) {
-                                               tface->mode= lasttface->mode;
-                                               tface->transp= lasttface->transp;
+                                               tf->mode= activetf->mode;
+                                               tf->transp= activetf->transp;
                                        } else if(event==1) {
-                                               memcpy(tface->uv, lasttface->uv, sizeof(tface->uv));
-                                               tface->tpage= lasttface->tpage;
-                                               tface->tile= lasttface->tile;
+                                               memcpy(tf->uv, activetf->uv, sizeof(tf->uv));
+                                               tf->tpage= activetf->tpage;
+                                               tf->tile= activetf->tile;
                                                
-                                               if(lasttface->mode & TF_TILES) tface->mode |= TF_TILES;
-                                               else tface->mode &= ~TF_TILES;
+                                               if(activetf->mode & TF_TILES) tf->mode |= TF_TILES;
+                                               else tf->mode &= ~TF_TILES;
                                                
                                        } else if(event==2)
-                                               memcpy(tface->col, lasttface->col, sizeof(tface->col));
+                                               memcpy(tf->col, activetf->col, sizeof(tf->col));
                                }
-                               tface++;
                        }
+
                        do_shared_vertexcol(me);        
                }
                break;
@@ -3784,7 +3776,12 @@ static void do_view3d_faceselmenu(void *arg, int event)
        case 9: /* mirror UVs */
                mirror_uv_tface();
                break;
-       
+       case 10: /* mark border seam */
+               seam_mark_clear_tface(1);
+               break;
+       case 11: /* clear seam */
+               seam_mark_clear_tface(2);
+               break;
        }
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWIMAGE, 0);
@@ -3795,8 +3792,6 @@ static uiBlock *view3d_faceselmenu(void *arg_unused)
        uiBlock *block;
        short yco= 0, menuwidth=120;
        
-       set_lasttface();
-       
        block= uiNewBlock(&curarea->uiblocks, "view3d_faceselmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
        uiBlockSetButmFunc(block, do_view3d_faceselmenu, NULL);
        
@@ -3817,6 +3812,11 @@ static uiBlock *view3d_faceselmenu(void *arg_unused)
        
        uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clear Seam|Ctrl E",              0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 11, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Mark Border Seam|Ctrl E",                0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 10, "");
+
+       uiDefBut(block, SEPR, 0, "",                            0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+
        uiDefIconTextBlockBut(block, view3d_facesel_showhidemenu, NULL, ICON_RIGHTARROW_THIN, "Show/Hide Faces", 0, yco-=20, 120, 19, "");
 
        if(curarea->headertype==HEADERTOP) {
index 5f5c9c39f3b91b4f2e97ea6e51765457c0500553..043ece745230329c250ba7a0298731a8edca6398 100644 (file)
@@ -4,6 +4,7 @@
 #include "BLI_memarena.h"
 #include "BLI_arithb.h"
 #include "BLI_rand.h"
+#include "BLI_heap.h"
 
 #include "BKE_utildefines.h"
 
@@ -129,148 +130,6 @@ static PHashLink *phash_next(PHash *ph, PHashKey key, PHashLink *link)
        return link;
 }
 
-/* Heap */
-
-#define PHEAP_PARENT(i) ((i-1)>>1)
-#define PHEAP_LEFT(i)   ((i<<1)+1)
-#define PHEAP_RIGHT(i)  ((i<<1)+2)
-#define PHEAP_COMPARE(a, b) (a->value < b->value)
-#define PHEAP_EQUALS(a, b) (a->value == b->value)
-#define PHEAP_SWAP(heap, i, j) \
-       { SWAP(int, heap->tree[i]->index, heap->tree[j]->index); \
-         SWAP(PHeapLink*, heap->tree[i], heap->tree[j]);  }
-
-static void pheap_down(PHeap *heap, int i)
-{
-       while (P_TRUE) {
-               int size = heap->size, smallest;
-               int l = PHEAP_LEFT(i);
-               int r = PHEAP_RIGHT(i);
-
-               smallest = ((l < size) && PHEAP_COMPARE(heap->tree[l], heap->tree[i]))? l: i;
-
-               if ((r < size) && PHEAP_COMPARE(heap->tree[r], heap->tree[smallest]))
-                       smallest = r;
-               
-               if (smallest == i)
-                       break;
-
-               PHEAP_SWAP(heap, i, smallest);
-               i = smallest;
-       }
-}
-
-static void pheap_up(PHeap *heap, int i)
-{
-       while (i > 0) {
-               int p = PHEAP_PARENT(i);
-
-               if (PHEAP_COMPARE(heap->tree[p], heap->tree[i]))
-                       break;
-
-               PHEAP_SWAP(heap, p, i);
-               i = p;
-       }
-}
-
-static PHeap *pheap_new()
-{
-       PHeap *heap = (PHeap*)MEM_callocN(sizeof(PHeap), "PHeap");
-       heap->bufsize = 1;
-       heap->tree = (PHeapLink**)MEM_mallocN(sizeof(PHeapLink*), "PHeapTree");
-       heap->arena = BLI_memarena_new(1<<16);
-
-       return heap;
-}
-
-static void pheap_delete(PHeap *heap)
-{
-       MEM_freeN(heap->tree);
-       BLI_memarena_free(heap->arena);
-       MEM_freeN(heap);
-}
-
-static PHeapLink *pheap_insert(PHeap *heap, float value, void *ptr)
-{
-       PHeapLink *link;
-
-       if ((heap->size + 1) > heap->bufsize) {
-               int newsize = heap->bufsize*2;
-
-               PHeapLink **ntree = (PHeapLink**)MEM_mallocN(newsize*sizeof(PHeapLink*), "PHeapTree");
-               memcpy(ntree, heap->tree, sizeof(PHeapLink*)*heap->size);
-               MEM_freeN(heap->tree);
-
-               heap->tree = ntree;
-               heap->bufsize = newsize;
-       }
-
-       param_assert(heap->size < heap->bufsize);
-
-       if (heap->freelinks) {
-               link = heap->freelinks;
-               heap->freelinks = (PHeapLink*)(((PHeapLink*)heap->freelinks)->ptr);
-       }
-       else
-               link = (PHeapLink*)BLI_memarena_alloc(heap->arena, sizeof *link);
-       link->value = value;
-       link->ptr = ptr;
-       link->index = heap->size;
-
-       heap->tree[link->index] = link;
-
-       heap->size++;
-
-       pheap_up(heap, heap->size-1);
-
-       return link;
-}
-
-#if 0
-static int pheap_empty(PHeap *heap)
-{
-       return (heap->size == 0);
-}
-
-static PHeapLink *pheap_toplink(PHeap *heap)
-{
-       return heap->tree[0];
-}
-#endif
-
-static void *pheap_popmin(PHeap *heap)
-{
-       void *ptr = heap->tree[0]->ptr;
-
-       heap->tree[0]->ptr = heap->freelinks;
-       heap->freelinks = heap->tree[0];
-
-       if (heap->size == 1)
-               heap->size--;
-       else {
-               PHEAP_SWAP(heap, 0, heap->size-1);
-               heap->size--;
-
-               pheap_down(heap, 0);
-       }
-
-       return ptr;
-}
-
-static void pheap_remove(PHeap *heap, PHeapLink *link)
-{
-       int i = link->index;
-
-       while (i > 0) {
-               int p = PHEAP_PARENT(i);
-
-               PHEAP_SWAP(heap, p, i);
-               i = p;
-       }
-
-       pheap_popmin(heap);
-}
-
 /* Geometry */
 
 static float p_vec_angle_cos(float *v1, float *v2, float *v3)
@@ -1110,13 +969,13 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
        PEdge *e, *e1, *e2;
        PHashKey vkeys[3];
        PFace *f;
-       struct PHeap *heap = pheap_new(nedges);
+       struct Heap *heap = BLI_heap_new();
        float angle;
 
        e = be;
        do {
                angle = p_edge_boundary_angle(e);
-               e->u.heaplink = pheap_insert(heap, angle, e);
+               e->u.heaplink = BLI_heap_insert(heap, angle, e);
 
                e = p_boundary_edge_next(e);
        } while(e != be);
@@ -1127,20 +986,20 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
                e->pair = be;
                be->pair = e;
 
-               pheap_remove(heap, e->u.heaplink);
-               pheap_remove(heap, be->u.heaplink);
+               BLI_heap_remove(heap, e->u.heaplink);
+               BLI_heap_remove(heap, be->u.heaplink);
        }
        else {
                while (nedges > 2) {
                        PEdge *ne, *ne1, *ne2;
 
-                       e = (PEdge*)pheap_popmin(heap);
+                       e = (PEdge*)BLI_heap_popmin(heap);
 
                        e1 = p_boundary_edge_prev(e);
                        e2 = p_boundary_edge_next(e);
 
-                       pheap_remove(heap, e1->u.heaplink);
-                       pheap_remove(heap, e2->u.heaplink);
+                       BLI_heap_remove(heap, e1->u.heaplink);
+                       BLI_heap_remove(heap, e2->u.heaplink);
                        e->u.heaplink = e1->u.heaplink = e2->u.heaplink = NULL;
 
                        e->flag |= PEDGE_FILLED;
@@ -1175,15 +1034,15 @@ static void p_chart_fill_boundary(PChart *chart, PEdge *be, int nedges)
                        else {
                                ne2->vert->edge = ne2;
                                
-                               ne2->u.heaplink = pheap_insert(heap, p_edge_boundary_angle(ne2), ne2);
-                               e2->u.heaplink = pheap_insert(heap, p_edge_boundary_angle(e2), e2);
+                               ne2->u.heaplink = BLI_heap_insert(heap, p_edge_boundary_angle(ne2), ne2);
+                               e2->u.heaplink = BLI_heap_insert(heap, p_edge_boundary_angle(e2), e2);
                        }
 
                        nedges--;
                }
        }
 
-       pheap_delete(heap);
+       BLI_heap_free(heap, NULL);
 }
 
 static void p_chart_fill_boundaries(PChart *chart, PEdge *outer)
@@ -2008,7 +1867,7 @@ static void p_chart_simplify_compute(PChart *chart)
           collapsed may then be view as stacks, where the next collapse/split
           is at the top of the respective lists. */
 
-       PHeap *heap = pheap_new();
+       Heap *heap = BLI_heap_new();
        PVert *v, **wheelverts;
        PEdge *collapsededges = NULL, *e;
        int nwheelverts, i, ncollapsed = 0;
@@ -2023,7 +1882,7 @@ static void p_chart_simplify_compute(PChart *chart)
                p_collapse_cost_vertex(v, &cost, &e);
 
                if (e)
-                       v->u.heaplink = pheap_insert(heap, cost, e);
+                       v->u.heaplink = BLI_heap_insert(heap, cost, e);
                else
                        v->u.heaplink = NULL;
        }
@@ -2032,12 +1891,12 @@ static void p_chart_simplify_compute(PChart *chart)
                e->u.nextcollapse = NULL;
 
        /* pop edge collapse out of heap one by one */
-       while (!pheap_empty(heap)) {
+       while (!BLI_heap_empty(heap)) {
                if (ncollapsed == NCOLLAPSE)
                        break;
 
-               PHeapLink *link = pheap_toplink(heap);
-               PEdge *edge = (PEdge*)pheap_popmin(heap), *pair = edge->pair;
+               HeapNode *link = BLI_heap_top(heap);
+               PEdge *edge = (PEdge*)BLI_heap_popmin(heap), *pair = edge->pair;
                PVert *oldv, *keepv;
                PEdge *wheele, *nexte;
 
@@ -2081,21 +1940,21 @@ static void p_chart_simplify_compute(PChart *chart)
                        v = wheelverts[i];
 
                        if (v->u.heaplink) {
-                               pheap_remove(heap, v->u.heaplink);
+                               BLI_heap_remove(heap, v->u.heaplink);
                                v->u.heaplink = NULL;
                        }
                
                        p_collapse_cost_vertex(v, &cost, &collapse);
 
                        if (collapse)
-                               v->u.heaplink = pheap_insert(heap, cost, collapse);
+                               v->u.heaplink = BLI_heap_insert(heap, cost, collapse);
                }
 
                ncollapsed++;
        }
 
        MEM_freeN(wheelverts);
-       pheap_delete(heap);
+       BLI_heap_free(heap, NULL);
 
        p_chart_post_collapse_flush(chart, collapsededges);
 }
index 1e3e7072c4822bfb973cb719bbac4b14cec88425..f5eeed656b82e6d8e753c179f915adc3d7efecf0 100644 (file)
@@ -51,23 +51,6 @@ struct PFace;
 struct PChart;
 struct PHandle;
 
-/* Heap */
-
-typedef struct PHeapLink {
-       void *ptr;
-       float value;
-       int index;
-} PHeapLink;
-
-typedef struct PHeap {
-       unsigned int size;
-       unsigned int bufsize;
-       MemArena *arena;
-       PHeapLink *freelinks;
-       PHeapLink *links;
-       PHeapLink **tree;
-} PHeap;
-
 /* Simplices */
 
 typedef struct PVert {
@@ -77,7 +60,7 @@ typedef struct PVert {
                PHashKey key;                   /* construct */
                int id;                                 /* abf/lscm matrix index */
                float distortion;               /* area smoothing */
-               PHeapLink *heaplink;    /* edge collapsing */
+               HeapNode *heaplink;             /* edge collapsing */
        } u;
 
        struct PEdge *edge;
@@ -93,7 +76,7 @@ typedef struct PEdge {
        union PEdgeUnion {
                PHashKey key;                                   /* construct */
                int id;                                                 /* abf matrix index */
-               PHeapLink *heaplink;                    /* fill holes */
+               HeapNode *heaplink;                             /* fill holes */
                struct PEdge *nextcollapse;             /* simplification */
        } u;
 
index d005e1473a1e29110b61d1bd26176618f0311afa..5319969e9abc8b06f905432c40f16ccba0e589d2 100644 (file)
@@ -1265,6 +1265,8 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                else if (G.qual==LR_CTRLKEY) {
                                        if(G.obedit && G.obedit->type==OB_MESH)
                                                Edge_Menu();
+                                       else if (G.f & G_FACESELECT)
+                                               seam_mark_clear_tface(0);
                                }
                                else if (G.qual==LR_SHIFTKEY) {
                                        if (G.obedit && G.obedit->type==OB_MESH) {
@@ -3992,7 +3994,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                break;
                        case EKEY :
                                if(okee("Unwrap"))
-                                       unwrap_lscm();
+                                       unwrap_lscm(0);
                                break;
                        case GKEY:
                                if((G.qual==0) && is_uv_tface_editing_allowed()) {
index a3ade13126f3e2afbcf021b97cf4d70bd272f3ea..fdf68b61a5a0772807fdadfed3a3989464d98992 100644 (file)
 #include "blendef.h"
 #include "mydevice.h"
 
-#include "ONL_opennl.h"
 #include "BDR_unwrapper.h"
 
 #include "PIL_time.h"
 
 #include "parametrizer.h"
 
-/* Implementation Least Squares Conformal Maps parameterization, based on
- * chapter 2 of:
- * Bruno Levy, Sylvain Petitjean, Nicolas Ray, Jerome Maillot. Least Squares
- * Conformal Maps for Automatic Texture Atlas Generation. In Siggraph 2002,
- * July 2002.
- */
-/* Data structure defines */
-#define LSCM_SEAM1   1
-#define LSCM_SEAM2   2
-#define LSCM_INDEXED 4
-#define LSCM_PINNED  8
-
-/* LscmVert = One UV */
-typedef struct LscmVert {
-       int v, v1, v2;            /* vertex indices */
-       int index;                /* index in solver */
-       short tf_index;           /* index in tface (0, 1, 2 or 3) */
-       short flag;               /* see above LSCM constants */
-       TFace *tf;                /* original tface */
-} LscmVert;
-
-/* QuickSort helper function, sort by vertex id */
-static int comp_lscmvert(const void *u1, const void *u2)
-{
-       LscmVert *v1, *v2;
-       
-       v1= *((LscmVert**)u1);
-       v2= *((LscmVert**)u2);
-
-       if (v1->v > v2->v) return 1;
-       else if (v1->v < v2->v) return -1;
-       return 0;
-}
-
-/* Hashed edge table utility */
+/* Set tface seams based on edge data, uses hash table to find seam edges. */
 
 static void hash_add_face(EdgeHash *ehash, MFace *mf)
 {
@@ -116,1149 +80,23 @@ static void hash_add_face(EdgeHash *ehash, MFace *mf)
                BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
 }
 
-/* divide selected faces in groups, based on seams. note that group numbering
-   starts at 1 */
-static int make_seam_groups(Mesh *me, int **seamgroups)
-{
-       int a, b, gid;
-       TFace *tf, *tface;
-       MFace *mf, *mface;
-       int *gf, *gface, *groups;
-       EdgeHash *ehash;
-       int doit, mark;
-
-       if(!me || !me->tface) return 0;
-
-       groups= (int*)MEM_callocN(sizeof(int)*me->totface, "SeamGroups");
-
-       ehash= BLI_edgehash_new();
-
-       mface= (MFace*)me->mface;
-       tface= (TFace*)me->tface;
-       gface= groups;
-       gid= 0;
-       for(b=me->totface; b>0; b--, mface++, tface++, gface++) {
-               if(!(tface->flag & TF_SELECT) || *gface!=0) continue;
-
-               if(gid != 0)
-                       BLI_edgehash_clear(ehash, NULL);
-
-               gid++;
-               *gface= gid;
-               mark= 0;
-               doit= 1;
-
-
-               while(doit) {
-                       doit= 0;
-               
-                       /* select connected: fill array */
-                       tf= tface;
-                       mf= mface;
-                       gf= gface;
-                       a= b;
-                       while(a--) {
-                               if(tf->flag & TF_HIDE);
-                               else if(tf->flag & TF_SELECT && *gf==gid) {
-                                       hash_add_face(ehash, mf);
-                               }
-                               tf++; mf++; gf++;
-                       }
-               
-                       /* select the faces using array
-                        * consider faces connected when they share one non-seam edge */
-                       tf= tface;
-                       mf= mface;
-                       gf= gface;
-                       a= b;
-                       while(a--) {
-                               if(tf->flag & TF_HIDE);
-                               else if(tf->flag & TF_SELECT && *gf==0) {
-                                       mark= 0;
-       
-                                       if(!(tf->unwrap & TF_SEAM1))
-                                               if(BLI_edgehash_haskey(ehash, mf->v1, mf->v2))
-                                                       mark= 1;
-                                       if(!(tf->unwrap & TF_SEAM2))
-                                               if(BLI_edgehash_haskey(ehash, mf->v2, mf->v3))
-                                                       mark= 1;
-                                       if(!(tf->unwrap & TF_SEAM3)) {
-                                               if(mf->v4) {
-                                                       if(BLI_edgehash_haskey(ehash, mf->v3, mf->v4))
-                                                               mark= 1;
-                                               }
-                                               else if(BLI_edgehash_haskey(ehash, mf->v3, mf->v1))
-                                                       mark= 1;
-                                       }
-                                       if(mf->v4 && !(tf->unwrap & TF_SEAM4))
-                                               if(BLI_edgehash_haskey(ehash, mf->v4, mf->v1))
-                                                       mark= 1;
-       
-                                       if(mark) {
-                                               *gf= gid;
-                                               doit= 1;
-                                       }
-                               }
-                               tf++; mf++; gf++;
-                       }
-               }
-       }
-
-       BLI_edgehash_free(ehash, NULL);
-       *seamgroups= groups;
-
-       return gid;
-}
-
-static void lscm_rotate_vert(int a, LscmVert **sortvert, int v2, int index)
-{
-       LscmVert **sv, *v;
-       int found, b;
-
-       /* starting from edge sortvert->v,v2, rotate around vertex and set
-        * index until a seam or an already marked tri is encountered */
-       found = 1;
-
-       while(found) {
-               found= 0;
-               sv=sortvert;
-
-               for(b=a; b>0 && ((*sv)->v == (*sortvert)->v) && !found; b--, sv++) {
-                       v= *sv;
-
-                       if(v->flag & LSCM_INDEXED);
-                       else if(v->v1 == v2) {
-                               v2= v->v2;
-
-                               if(v->flag & LSCM_SEAM1) break;
-
-                               v->index= index;
-                               v->flag |= LSCM_INDEXED;
-                               found= 1;
-                               break;
-                       }
-                       else if(v->v2==v2) {
-                               v2= v->v1;
-
-                               if(v->flag & LSCM_SEAM2) break;
-
-                               v->index= index;
-                               v->flag |= LSCM_INDEXED;
-                               found= 1;
-                               break;
-                       }
-               }
-       }
-}
-
-static int lscm_vertex_set_index(int a, LscmVert **sortvert, int totindex)
-{
-       LscmVert **sv, *v;
-       int index, b;
-
-       /* rotate over 'wheel' of faces around vertex, incrementing the index
-          everytime we meet a seam, or no next connected face is found.
-          repeat this until we have and id for all verts.
-          if mesh is non-manifold, non-manifold edges will be cut randomly */
-
-       index= totindex;
-       sv= sortvert;
-
-       for(b=a; b>0 && ((*sv)->v == (*sortvert)->v); b--, sv++) {
-               v= *sv;
-
-               if(v->flag & LSCM_INDEXED) continue;
-
-               v->index= index;
-               v->flag |= LSCM_INDEXED;
-
-               lscm_rotate_vert(b, sv, v->v1, index);
-               lscm_rotate_vert(b, sv, v->v2, index);
-
-               index++;
-       }
-
-       return index;
-}
-
-static int lscm_set_indices(LscmVert **sortvert, int totvert)
-{
-       LscmVert *v, **sv;
-       int a, lastvert, totindex;
-
-       totindex= 0;
-       lastvert= -1;
-       sv= sortvert;
-
-       for(a=totvert; a>0; a--, sv++) {
-               v= *sv;
-               if(v->v != lastvert) {
-                       totindex= lscm_vertex_set_index(a, sv, totindex);
-                       lastvert= v->v;
-               }
-       }
-
-       return totindex;
-}
-
-static void lscm_normalize(float *co, float *center, float radius)
-{
-       /* normalize relative to complete surface */
-       VecSubf(co, co, center);
-       VecMulf(co, (float)1.0/radius);
-}
-
-static void lscm_add_triangle(float *v1, float *v2, float *v3, int vid1, int vid2, int vid3, float *center, float radius)
-{
-       float x[3], y[3], z[3], sub[3], z1[2], z2[2];
-       int id0[2], id1[2], id2[2];
-
-       /* project 3d triangle
-        * edge length is lost, as this algorithm is angle based */
-       lscm_normalize(v1, center, radius);
-       lscm_normalize(v2, center, radius);
-       lscm_normalize(v3, center, radius);
-
-       VecSubf(x, v2, v1);
-       Normalise(x);
-
-       VecSubf(sub, v3, v1);
-       Crossf(z, x, sub);
-       Normalise(z);
-
-       Crossf(y, z, x);
-
-       /* reduce to two 2d vectors */
-       VecSubf(sub, v2, v1);
-       z1[0]= Normalise(sub);
-       z1[1]= 0;
-
-       VecSubf(sub, v3, v1);
-       z2[0]= Inpf(sub, x);
-       z2[1]= Inpf(sub, y);
-
-       /* split id's up for u and v
-          id = u, id + 1 = v */
-       id0[0]= 2*vid1;
-       id0[1]= 2*vid1 + 1;
-       id1[0]= 2*vid2;
-       id1[1]= 2*vid2 + 1;
-       id2[0]= 2*vid3;
-       id2[1]= 2*vid3 + 1;
-
-       /* The LSCM Equation:
-        * ------------------
-        * (u,v) are the uv coords we are looking for -> complex number u + i*v
-        * (x,y) are the above calculated local coords -> complex number x + i*y
-        * Uk = uk + i*vk
-        * Zk = xk + i*yk (= zk[0] + i*zk[1] in the code)
-        * 
-        * That makes the equation:
-        * (Z1 - Z0)(U2 - U0) = (Z2 - Z0)(U1 - U0)
-        *
-        * x0, y0 and y1 were made zero by projecting the triangle:
-        * (x1 + i*y1)(u2 + i*v2 - u0 - i*v0) = (x2 + i*y2)(u1 + i*v1 - u0 - i*v0)
-        *
-        * this gives the following coefficients:
-        * u0 * ((-x1 + x2) + i*(y2))
-        * v0 * ((-y2) + i*(-x1 + x2))
-        * u1 * ((-x2) + i*(-y2))
-        * v1 * ((y2) + i*(-x2))
-        * u2 * (x1)
-        * v2 * (i*(x1))
-        */
-
-       /* real part */
-       nlBegin(NL_ROW);
-       nlCoefficient(id0[0], -z1[0] + z2[0]);
-       nlCoefficient(id0[1], -z2[1]        );
-       nlCoefficient(id1[0], -z2[0]        );
-       nlCoefficient(id1[1],  z2[1]        );
-       nlCoefficient(id2[0],  z1[0]        );
-       nlEnd(NL_ROW);
-
-       /* imaginary  part */
-       nlBegin(NL_ROW);
-       nlCoefficient(id0[0],  z2[1]        );
-       nlCoefficient(id0[1], -z1[0] + z2[0]);
-       nlCoefficient(id1[0], -z2[1]        );
-       nlCoefficient(id1[1], -z2[0]        );
-       nlCoefficient(id2[1],  z1[0]        );
-       nlEnd(NL_ROW);
-}
-
-static float lscm_angle_cos(float *v1, float *v2, float *v3)
-{
-    float vec1[3], vec2[3];
-
-       VecSubf(vec1, v2, v1);
-       VecSubf(vec2, v3, v1);
-       Normalise(vec1);
-       Normalise(vec2);
-
-       return vec1[0]*vec2[0] + vec1[1]*vec2[1] + vec1[2]*vec2[2];
-}
-
-static int lscm_build_vertex_data(Mesh *me, int *groups, int gid, LscmVert **lscm_vertices, LscmVert ***sort_vertices)
-{
-       MVert *mv;
-       MFace *mf;
-       TFace *tf;
-       int *gf, totvert, a;
-       LscmVert *lscmvert, **sortvert;
-       LscmVert *v1, *v2, *v3, **sv1, **sv2, **sv3;
-       float a1, a2;
-
-       /* determine size for malloc */
-       totvert= 0;
-       mv = me->mvert;
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-       a1 = a2 = 0;
-
-       for(a=me->totface; a>0; a--) {
-               if(*gf==gid) {
-
-                       totvert += 3;
-                       if(mf->v4) totvert +=3; 
-               }
-               tf++; mf++; gf++;
-       }
-
-       /* a list per face vertices */
-       lscmvert= (LscmVert*)MEM_mallocN(sizeof(LscmVert)*totvert,"LscmVerts");
-       /* the above list sorted by vertex id */
-       sortvert= (LscmVert**)MEM_mallocN(sizeof(LscmVert*)*totvert, "LscmVSort");
-
-       /* actually build the list (including virtual triangulation) */
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-
-       v1= lscmvert;
-       v2= lscmvert + 1;
-       v3= lscmvert + 2;
-
-       sv1= sortvert;
-       sv2= sortvert + 1;
-       sv3= sortvert + 2;
-
-       /* warning: ugly code :) */
-       for(a=me->totface; a>0; a--) {
-               if(*gf==gid) {
-                       /* determine triangulation direction, to avoid degenerate
-                          triangles (small cos = degenerate). */
-                       if(mf->v4) {
-                               a1 = lscm_angle_cos((mv+mf->v1)->co, (mv+mf->v2)->co, (mv+mf->v3)->co);
-                               a1 += lscm_angle_cos((mv+mf->v2)->co, (mv+mf->v1)->co, (mv+mf->v3)->co);
-                               a1 += lscm_angle_cos((mv+mf->v3)->co, (mv+mf->v1)->co, (mv+mf->v2)->co);
-
-                               a2 = lscm_angle_cos((mv+mf->v1)->co, (mv+mf->v2)->co, (mv+mf->v4)->co);
-                               a2 += lscm_angle_cos((mv+mf->v2)->co, (mv+mf->v1)->co, (mv+mf->v4)->co);
-                               a2 += lscm_angle_cos((mv+mf->v4)->co, (mv+mf->v1)->co, (mv+mf->v2)->co);
-                       }
-
-                       a1 = 0.0; a2 = 1.0;
-
-                       if(!mf->v4 || a1 > a2) {
-                               v1->v= mf->v1;
-                               v2->v= mf->v2;
-                               v3->v= mf->v3;
-
-                               v1->tf_index= 0;
-                               v2->tf_index= 1;
-                               v3->tf_index= 2;
-
-                               v1->flag= v2->flag= v3->flag= 0;
-
-                               v1->v1= v2->v;
-                               v1->v2= v3->v;
-
-                               v2->v1= v1->v;
-                               v2->v2= v3->v;
-
-                               v3->v1= v1->v;
-                               v3->v2= v2->v;
-
-                               v1->tf= v2->tf= v3->tf= tf;
-
-                               *sv1= v1;
-                               *sv2= v2;
-                               *sv3= v3;
-
-                               if(tf->unwrap & TF_SEAM1) {
-                                       v1->flag |= LSCM_SEAM1;
-                                       v2->flag |= LSCM_SEAM1;
-                               }
-       
-                               if(tf->unwrap & TF_SEAM2) {
-                                       v2->flag |= LSCM_SEAM2;
-                                       v3->flag |= LSCM_SEAM2;
-                               }
-
-                               if(!mf->v4 && tf->unwrap & TF_SEAM3) {
-                                       v1->flag |= LSCM_SEAM2;
-                                       v3->flag |= LSCM_SEAM1;
-                               }
-
-                               v1 += 3; v2 += 3; v3 += 3;
-                               sv1 += 3; sv2 += 3; sv3 += 3;
-                       }
-
-                       if(mf->v4 && a1 > a2) {
-                               v1->v= mf->v1;
-                               v2->v= mf->v3;
-                               v3->v= mf->v4;
-
-                               v1->tf_index= 0;
-                               v2->tf_index= 2;
-                               v3->tf_index= 3;
-
-                               v1->flag= v2->flag= v3->flag= 0;
-
-                               v1->v1= v2->v;
-                               v1->v2= v3->v;
-
-                               v2->v1= v3->v;
-                               v2->v2= v1->v;
-       
-                               v3->v1= v1->v;
-                               v3->v2= v2->v;
-
-                               v1->tf= v2->tf= v3->tf= tf;
-
-                               *sv1= v1;
-                               *sv2= v2;
-                               *sv3= v3;
-
-                               if(tf->unwrap & TF_SEAM3) {
-                                       v2->flag |= LSCM_SEAM1;
-                                       v3->flag |= LSCM_SEAM2;
-                               }
-       
-                               if(tf->unwrap & TF_SEAM4) {
-                                       v1->flag |= LSCM_SEAM2;
-                                       v3->flag |= LSCM_SEAM1;
-                               }
-
-                               v1 += 3; v2 += 3; v3 += 3;
-                               sv1 += 3; sv2 += 3; sv3 += 3;
-                       }
-
-                       if(mf->v4 && a1 <= a2) {
-                               v1->v= mf->v1;
-                               v2->v= mf->v2;
-                               v3->v= mf->v4;
-
-                               v1->tf_index= 0;
-                               v2->tf_index= 1;
-                               v3->tf_index= 3;
-
-                               v1->flag= v2->flag= v3->flag= 0;
-
-                               v1->v1= v2->v;
-                               v1->v2= v3->v;
-
-                               v2->v1= v1->v;
-                               v2->v2= v3->v;
-
-                               v3->v1= v1->v;
-                               v3->v2= v2->v;
-
-                               v1->tf= v2->tf= v3->tf= tf;
-
-                               *sv1= v1;
-                               *sv2= v2;
-                               *sv3= v3;
-
-                               if(tf->unwrap & TF_SEAM1) {
-                                       v1->flag |= LSCM_SEAM1;
-                                       v2->flag |= LSCM_SEAM1;
-                               }
-       
-                               if(tf->unwrap & TF_SEAM4) {
-                                       v1->flag |= LSCM_SEAM2;
-                                       v3->flag |= LSCM_SEAM1;
-                               }
-
-                               v1 += 3; v2 += 3; v3 += 3;
-                               sv1 += 3; sv2 += 3; sv3 += 3;
-
-                               /* -- */
-
-                               v1->v= mf->v2;
-                               v2->v= mf->v3;
-                               v3->v= mf->v4;
-
-                               v1->tf_index= 1;
-                               v2->tf_index= 2;
-                               v3->tf_index= 3;
-
-                               v1->flag= v2->flag= v3->flag= 0;
-
-                               v1->v1= v2->v;
-                               v1->v2= v3->v;
-
-                               v2->v1= v1->v;
-                               v2->v2= v3->v;
-       
-                               v3->v1= v1->v;
-                               v3->v2= v2->v;
-
-                               v1->tf= v2->tf= v3->tf= tf;
-
-                               *sv1= v1;
-                               *sv2= v2;
-                               *sv3= v3;
-
-                               if(tf->unwrap & TF_SEAM2) {
-                                       v1->flag |= LSCM_SEAM1;
-                                       v2->flag |= LSCM_SEAM1;
-                               }
-       
-                               if(tf->unwrap & TF_SEAM3) {
-                                       v2->flag |= LSCM_SEAM2;
-                                       v3->flag |= LSCM_SEAM2;
-                               }
-
-                               v1 += 3; v2 += 3; v3 += 3;
-                               sv1 += 3; sv2 += 3; sv3 += 3;
-                       }
-
-               }
-               tf++; mf++; gf++;
-       }
-
-       /* sort by vertex id */
-       qsort(sortvert, totvert, sizeof(LscmVert*), comp_lscmvert);
-       
-       *lscm_vertices= lscmvert;
-       *sort_vertices= sortvert;
-       return totvert;
-}
-
-static void lscm_min_max_cent_rad(Mesh *me, LscmVert **sortvert, int totvert, float *min, float *max, float *center, float *radius)
-{
-       MVert *mv= me->mvert;
-       LscmVert *v, **sv;
-       int a, lastvert, vertcount;
-       float *co, sub[3];
-       
-       /* find min, max and center */
-       center[0]= center[1]= center[2]= 0.0;
-       INIT_MINMAX(min, max);
-
-       vertcount= 0;
-       lastvert= -1;
-       sv= sortvert;
-
-       for(a=totvert; a>0; a--, sv++) {
-               v= *sv;
-               if(v->v != lastvert) {
-                       co= (mv+v->v)->co;
-
-                       VecAddf(center, center, (mv+v->v)->co);
-                       DO_MINMAX(co, min, max);
-
-                       vertcount++;
-                       lastvert= v->v;
-               }
-       }
-
-       VecMulf(center, (float)1.0/(float)vertcount);
-
-       /* find radius */
-       VecSubf(sub, center, max);
-       *radius= Normalise(sub);
-
-       if(*radius < 1e-20)
-               *radius= 1.0;
-}
-
-static void lscm_projection_axes(float *min, float *max, float *p1, float *p2)
-{
-       float dx, dy, dz;
-
-       dx= max[0] - min[0];
-       dy= max[1] - min[1];
-       dz= max[2] - min[2];
-
-       p1[0]= p1[1]= p1[2]= 0.0;
-       p2[0]= p2[1]= p2[2]= 0.0;
-
-       if(dx < dy && dx < dz) {
-               if(dy > dz) p1[1]= p2[2]= 1.0;   /* y, z */
-               else p1[2]= p2[1]= 1.0;          /* z, y */
-       }
-       else if(dy < dx && dy < dz) {
-               if(dx > dz) p1[0]= p2[2]= 1.0;   /* x, z */
-               else p1[2]= p2[0]= 1.0;          /* z, x */
-       }
-       else {
-               if(dx > dy) p1[0]= p2[1]= 1.0;   /* x, y */
-               else p1[1]= p2[0]= 1.0;          /* y, x */
-       }
-}
-
-static void lscm_set_initial_solution(Mesh *me, LscmVert **sortvert, int totvert, float *p1, float *p2, int *vertex_min, int *vertex_max)
-{
-       float umin, umax, *uv, *co;
-       int vmin, vmax, a;
-       LscmVert **sv, *v;
-       MVert *mv= me->mvert;
-
-       umin= 1.0e30;
-       umax= -1.0e30;
-
-       vmin= 0;
-       vmax= 2;
-
-       sv= sortvert;
-
-       for(a=totvert; a>0; a--, sv++) {
-               v= *sv;
-               co= (mv+v->v)->co;
-               uv= v->tf->uv[v->tf_index];
-
-               uv[0]= Inpf(co, p1);
-               uv[1]= Inpf(co, p2);
-               
-               if(uv[0] < umin) {
-                       vmin= v->index;
-                       umin= uv[0];
-               }
-               if(uv[0] > umax) {
-                       vmax= v->index;
-                       umax= uv[0];
-               }
-
-               nlSetVariable(2*v->index, uv[0]);
-               nlSetVariable(2*v->index + 1, uv[1]);
-       }
-
-       *vertex_min= vmin;
-       *vertex_max= vmax;
-}
-
-static void lscm_set_pinned_solution(Mesh *me, LscmVert **sortvert, int totvert, int *pinned)
-{
-       float min[2], max[2], *uv, *co;
-       int a, pin;
-       LscmVert **sv, *v;
-       MVert *mv= me->mvert;
-
-       INIT_MINMAX2(min, max);
-       *pinned= 0;
-
-       sv= sortvert;
-
-       for(a=totvert; a>0; a--, sv++) {
-               v= *sv;
-               co= (mv+v->v)->co;
-               uv= v->tf->uv[v->tf_index];
-
-               pin = ((v->tf->unwrap & TF_PIN1) && (v->tf_index == 0)) ||
-                     ((v->tf->unwrap & TF_PIN2) && (v->tf_index == 1)) ||
-                     ((v->tf->unwrap & TF_PIN3) && (v->tf_index == 2)) ||
-                     ((v->tf->unwrap & TF_PIN4) && (v->tf_index == 3)); 
-
-               nlSetVariable(2*v->index, uv[0]);
-               nlSetVariable(2*v->index + 1, uv[1]);
-
-        if(pin){
-                       DO_MINMAX2(uv, min, max);
-
-                       *pinned += 1;
-
-                       nlLockVariable(2*v->index);
-                       nlLockVariable(2*v->index + 1);
-               }
-       }
-
-       if (*pinned){
-               /* abuse umax vmax for caculating euclidian distance */
-               max[0] -= min[0];
-               max[1] -= min[1];
-
-               /* check for degenerated pinning box */
-               if (((max[0]*max[0])+(max[1]*max[1])) < 1e-10)
-                       *pinned = -1;
-       }
-}
-
-
-static void lscm_build_matrix(Mesh *me, LscmVert *lscmvert, int *groups, int gid, float *center, float radius)
-{
-       MVert *mv= me->mvert;
-       MFace *mf;
-       TFace *tf;
-       int *gf, a, id1, id2, id3;
-       LscmVert *v;
-       float co1[3], co2[3], co3[3];
-
-       nlBegin(NL_MATRIX);
-
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-       v= lscmvert;
-
-       for(a=me->totface; a>0; a--) {
-               if(*gf==gid) {
-                       VecCopyf(co1, (mv+v->v)->co);
-                       id1= v->index; v++;
-                       VecCopyf(co2, (mv+v->v)->co);
-                       id2= v->index; v++;
-                       VecCopyf(co3, (mv+v->v)->co);
-                       id3= v->index; v++;
-                       lscm_add_triangle(co1, co2, co3, id1, id2, id3, center, radius);
-
-                       if(mf->v4) {
-                               VecCopyf(co1, (mv+v->v)->co);
-                               id1= v->index; v++;
-                               VecCopyf(co2, (mv+v->v)->co);
-                               id2= v->index; v++;
-                               VecCopyf(co3, (mv+v->v)->co);
-                               id3= v->index; v++;
-                               lscm_add_triangle(co1, co2, co3, id1, id2, id3, center, radius);
-                       } 
-               }
-               tf++; mf++; gf++;
-       }
-
-       nlEnd(NL_MATRIX);
-}
-
-static void lscm_load_solution(Mesh *me, LscmVert *lscmvert, int *groups, int gid)
-{
-       MFace *mf;
-       TFace *tf;
-       int *gf, a, b;
-       LscmVert *v;
-       float *uv;
-
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-       v= lscmvert;
-
-       for(a=me->totface; a>0; a--) {
-               if(*gf==gid) {
-
-                       if(mf->v4) b= 6;
-                       else b=3;
-
-                       /* index= u, index + 1= v */
-                       while(b > 0) {
-                               uv= v->tf->uv[v->tf_index];
-
-                               uv[0]= nlGetVariable(2*v->index);
-                               uv[1]= nlGetVariable(2*v->index + 1);
-
-                               v++;
-                               b--;
-                       }
-               }
-               tf++; mf++; gf++;
-       }
-}
-
-static int unwrap_lscm_face_group(Mesh *me, int *groups, int gid)
-{
-       LscmVert *lscmvert, **sortvert;
-       int totindex, totvert, vmin, vmax,pinned;
-       float min[3], max[3], center[3], radius, p1[3], p2[3];
-
-       /* build the data structures */
-       totvert= lscm_build_vertex_data(me, groups, gid, &lscmvert, &sortvert);
-
-       /* calculate min, max, center and radius */
-       lscm_min_max_cent_rad(me, sortvert, totvert, min, max, center, &radius);
-
-       /* index distinct vertices */
-       totindex= lscm_set_indices(sortvert, totvert);
-
-       /* create solver */
-       nlNewContext();
-       nlSolverParameteri(NL_NB_VARIABLES, 2*totindex);
-       nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE);
-
-       nlBegin(NL_SYSTEM);
-
-       /* find axes for projecting initial solutions on */
-       lscm_projection_axes(min, max, p1, p2);
-    /* see if pinned data is avail and set on fly */
-       lscm_set_pinned_solution(me, sortvert, totvert, &pinned);
-
-    if(pinned < 0); /* really small pinned uv's: won't see difference anyway */
-       else { 
-               /* auto pinning */
-               if(pinned < 2) 
-               {
-                       /* set initial solution and locate two extrema vertices to pin */
-                       lscm_set_initial_solution(me,sortvert,totvert,p1,p2,&vmin,&vmax);
-
-                       /* pin 2 uv's */
-                       nlLockVariable(2*vmin);
-                       nlLockVariable(2*vmin + 1);
-                       nlLockVariable(2*vmax);
-                       nlLockVariable(2*vmax + 1);
-               }
-
-               /* add triangles to the solver */
-               lscm_build_matrix(me, lscmvert, groups, gid, center, radius);
-               
-               nlEnd(NL_SYSTEM);
-
-               /* LSCM solver magic! */
-               nlSolve(NULL, NL_FALSE);
-               
-               /* load new uv's: will be projected uv's if solving failed  */
-               lscm_load_solution(me, lscmvert, groups, gid);
-    }
-
-       nlDeleteContext(nlGetCurrent());
-       MEM_freeN(lscmvert);
-       MEM_freeN(sortvert);
-       return (pinned);
-}
-
-static void seam_group_bbox(Mesh *me, int *groups, int gid, float *min, float *max)
-{
-       MFace *mf;
-       TFace *tf;
-       int *gf, a;
-
-       INIT_MINMAX2(min, max);
-
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-
-       for(a=me->totface; a>0; a--) {
-               if((gid!=0 && *gf==gid) || (gid==0 && *gf)) {
-                       
-                       DO_MINMAX2(tf->uv[0], min, max)
-                       DO_MINMAX2(tf->uv[1], min, max)
-                       DO_MINMAX2(tf->uv[2], min, max)
-
-                       if(mf->v4) { 
-                               DO_MINMAX2(tf->uv[3], min, max)
-                       }
-               }
-               tf++; mf++; gf++;
-       }
-}
-
-static void seam_group_scale(Mesh *me, int *groups, int gid, float scale)
-{
-       MFace *mf;
-       TFace *tf;
-       int *gf, a;
-
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-
-       for(a=me->totface; a>0; a--) {
-               if((gid!=0 && *gf==gid) || (gid==0 && *gf)) {
-                       
-                       Vec2Mulf(tf->uv[0], scale);
-                       Vec2Mulf(tf->uv[1], scale);
-                       Vec2Mulf(tf->uv[2], scale);
-                       if(mf->v4) Vec2Mulf(tf->uv[3], scale);
-               }
-               tf++; mf++; gf++;
-       }
-}
-
-static void seam_group_move(Mesh *me, int *groups, int gid, float add[2])
-{
-       MFace *mf;
-       TFace *tf;
-       int *gf, a;
-
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-
-       for(a=me->totface; a>0; a--) {
-               if((gid!=0 && *gf==gid) || (gid==0 && *gf)) {
-                       
-                       Vec2Addf(tf->uv[0], tf->uv[0], add);
-                       Vec2Addf(tf->uv[1], tf->uv[1], add);
-                       Vec2Addf(tf->uv[2], tf->uv[2], add);
-                       if(mf->v4) Vec2Addf(tf->uv[3], tf->uv[3], add);
-               }
-               tf++; mf++; gf++;
-       }
-}
-
-/* put group withing (0,0)->(1,1) boundbox */
-static void seam_group_normalize(Mesh *me, int *groups, int gid)
-{
-       float min[2], max[2], sx, sy, scale, add[2];
-
-       seam_group_bbox(me, groups, gid, min, max);
-
-       sx= (max[0]-min[0]);
-       sy= (max[1]-min[1]);
-
-       scale= MAX2(sx, sy);
-       scale= (1.0/scale);
-
-       add[0]= -min[0];
-       add[1]= -min[1];
-
-       seam_group_move(me, groups, gid, add);
-       seam_group_scale(me, groups, gid, scale);
-}
-
-/* get scale relative to mesh */
-static float seam_group_relative_scale(Mesh *me, int *groups, int gid)
-{
-       MVert *mv= me->mvert;
-       MFace *mf;
-       TFace *tf;
-       int *gf, a;
-       float len_xyz, len_uv;
-
-       len_xyz= 0.0;
-       len_uv= 0.0;
-       mf= me->mface;
-       tf= me->tface;
-       gf= groups;
-
-       for(a=me->totface; a>0; a--) {
-               if(*gf==gid) {
-                       
-                       len_uv += Vec2Lenf(tf->uv[0], tf->uv[1]);
-                       len_xyz += VecLenf((mv+mf->v1)->co, (mv+mf->v2)->co);
-
-                       len_uv += Vec2Lenf(tf->uv[1], tf->uv[2]);
-                       len_xyz += VecLenf((mv+mf->v2)->co, (mv+mf->v3)->co);
-
-                       if(mf->v4) { 
-
-                               len_uv += Vec2Lenf(tf->uv[2], tf->uv[3]);
-                               len_xyz += VecLenf((mv+mf->v3)->co, (mv+mf->v4)->co);
-                               
-                               len_uv += Vec2Lenf(tf->uv[3], tf->uv[0]);
-                               len_xyz += VecLenf((mv+mf->v4)->co, (mv+mf->v1)->co);
-                       }
-                       else {
-                               len_uv += Vec2Lenf(tf->uv[2], tf->uv[0]);
-                               len_xyz += VecLenf((mv+mf->v3)->co, (mv+mf->v1)->co);
-                       }
-               }
-               tf++; mf++; gf++;
-       }
-
-       return (len_uv/len_xyz);
-}
-
-/* very primitive packing */
-static void pack_seam_groups(Mesh *me, int *groups, int totgroup)
-{
-       float *groupscale, minscale, scale, add[2], groupw;
-       float dx, dy, packx, packy, min[2], max[2], rowh;
-       int a;
-
-       groupscale = (float*)MEM_mallocN(sizeof(float)*totgroup, "SeamGroupScale");
-
-       minscale= 1e30;
-
-       for(a=0; a<totgroup; a++) {
-               groupscale[a]= seam_group_relative_scale(me, groups, a+1);
-               minscale= MIN2(groupscale[a], minscale);
-       }
-
-       packx= packy= 0.0;
-       rowh= 0.0;
-       groupw= 1.0/sqrt(totgroup);
-
-       for(a=0; a<totgroup; a++) {
-
-               /* scale so all groups have the same size relative to the mesh */
-               scale = minscale/groupscale[a];
-               scale *= groupw;
-
-               seam_group_bbox(me, groups, a+1, min, max);
-               dx= (max[0]-min[0])*scale;
-               dy= (max[1]-min[1])*scale;
-
-               /* for padding */
-               dx += 0.01;
-               dy += 0.01;
-
-               add[0]= add[1]= 0.0;
-
-               if(dx > 1.0) {
-                       add[0]= 0.0;
-                       add[1]= packy;
-
-                       packy += dy;
-                       packx= 0.0;
-                       rowh= 0.0;
-               }
-               else if(dx <= (1.0-packx)) {
-                       add[0]= packx;
-                       add[1]= packy;
-
-                       packx += dx;
-                       rowh= MAX2(rowh, dy);
-               }
-               else {
-                       packy += rowh;
-                       packx= dx;
-                       rowh= dy;
-
-                       add[0]= 0.0;
-                       add[1]= packy;
-               }
-
-               /* for padding */
-               add[0] += 0.005;
-               add[1] += 0.005;
-
-               seam_group_scale(me, groups, a+1, scale);
-               seam_group_move(me, groups, a+1, add);
-       }
-
-       MEM_freeN(groupscale);
-
-       seam_group_normalize(me, groups, 0);
-       seam_group_scale(me, groups, 0, 0.98);
-       add[0]= add[1]= 0.01;
-       seam_group_move(me, groups, 0, add);
-}
-
-void unwrap_lscm(void)
-{
-    int dopack = 1;
-       int res;
-       Mesh *me;
-       int totgroup, *groups=NULL, a;
-
-       if (G.scene->toolsettings->unwrapper != 2) {
-               unwrap_lscm_new();
-               return;
-       }
-       
-       me= get_mesh(OBACT);
-       if(me==0 || me->tface==0) return;
-       
-       totgroup= make_seam_groups(me, &groups);
-       
-       if(totgroup==0) return;
-       
-       for(a=totgroup; a>0; a--) {
-               res= unwrap_lscm_face_group(me, groups, a);
-               if((res < 3) && (res > -1)) {
-                       seam_group_normalize(me, groups, a);
-               }
-               else {
-                       dopack = 0;
-               }
-               
-       }
-       
-       if(dopack) pack_seam_groups(me, groups, totgroup);
-       
-       MEM_freeN(groups);
-
-       BIF_undo_push("UV lscm unwrap");
-
-       object_uvs_changed(OBACT);
-
-       allqueue(REDRAWVIEW3D, 0);
-       allqueue(REDRAWIMAGE, 0);
-}
-
-/* note; to make it quick work, brecht/jens: you can make it nice later! (ton) */
-void unwrap_lscm_live(void)
-{
-    int dopack = 1;
-       int res;
-       Mesh *me;
-       int totgroup, *groups=NULL, a;
-       
-       me= get_mesh(OBACT);
-       if(me==0 || me->tface==0) return;
-       
-       totgroup= make_seam_groups(me, &groups);
-       
-       if(totgroup==0) return;
-       
-       for(a=totgroup; a>0; a--) {
-               res= unwrap_lscm_face_group(me, groups, a);
-               if((res < 3) && (res > -1)) {
-                       seam_group_normalize(me, groups, a);
-               }
-               else {
-                       dopack = 0;
-               }
-               
-       }
-       
-       if(dopack) pack_seam_groups(me, groups, totgroup);
-       
-       MEM_freeN(groups);
-
-}
-
-/* Set tface seams based on edge data, uses hash table to find seam edges. */
-
-void set_seamtface()
-{
-       Mesh *me;
-       EdgeHash *ehash;
-       int a;
-       MFace *mf;
-       TFace *tf;
-       MEdge *medge;
-
-       me= get_mesh(OBACT);
-       if(!me || !me->tface || !(G.f & G_FACESELECT)) return;
-       
-       ehash= BLI_edgehash_new();
-
-       for(medge=me->medge, a=me->totedge; a>0; a--, medge++)
-               if(medge->flag & ME_SEAM)
-                       BLI_edgehash_insert(ehash, medge->v1, medge->v2, NULL);
-
-       mf= me->mface;
-       tf= me->tface;
-       for(a=me->totface; a>0; a--, mf++, tf++) {
-               tf->unwrap &= ~(TF_SEAM1|TF_SEAM2|TF_SEAM3|TF_SEAM4);
-
-               if(!ehash) continue;
-
-               if(BLI_edgehash_haskey(ehash, mf->v1, mf->v2)) tf->unwrap |= TF_SEAM1;
-               if(BLI_edgehash_haskey(ehash, mf->v2, mf->v3)) tf->unwrap |= TF_SEAM2;
-
-               if(mf->v4) {
-                       if(BLI_edgehash_haskey(ehash, mf->v3, mf->v4)) tf->unwrap |= TF_SEAM3;
-                       if(BLI_edgehash_haskey(ehash, mf->v4, mf->v1)) tf->unwrap |= TF_SEAM4;
-               }
-               else if(BLI_edgehash_haskey(ehash, mf->v3, mf->v1)) tf->unwrap |= TF_SEAM3;
-       }
-
-       BLI_edgehash_free(ehash, NULL);
-}
-
 void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
 {
        TFace *tf;
        MFace *mf;
        int a, doit=1, mark=0;
        char *linkflag;
-       EdgeHash *ehash;
+       EdgeHash *ehash, *seamhash;
+       MEdge *med;
 
        ehash= BLI_edgehash_new();
+       seamhash = BLI_edgehash_new();
        linkflag= MEM_callocN(sizeof(char)*me->totface, "linkflaguv");
 
+       for(med=me->medge, a=0; a < me->totedge; a++, med++)
+               if(med->flag & ME_SEAM)
+                       BLI_edgehash_insert(seamhash, med->v1, med->v2, NULL);
+
        if (mode==0 || mode==1) {
                /* only put face under cursor in array */
                mf= ((MFace*)me->mface) + index;
@@ -1285,27 +123,29 @@ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
                tf= me->tface;
                mf= me->mface;
                for(a=0; a<me->totface; a++, tf++, mf++) {
-                       if(tf->flag & TF_HIDE);
-                       else if(!linkflag[a]) {
+                       if(tf->flag & TF_HIDE)
+                               continue;
+
+                       if(!linkflag[a]) {
                                mark= 0;
 
-                               if(!(tf->unwrap & TF_SEAM1))
+                               if(!BLI_edgehash_haskey(seamhash, mf->v1, mf->v2))
                                        if(BLI_edgehash_haskey(ehash, mf->v1, mf->v2))
                                                mark= 1;
-                               if(!(tf->unwrap & TF_SEAM2))
+                               if(!BLI_edgehash_haskey(seamhash, mf->v2, mf->v3))
                                        if(BLI_edgehash_haskey(ehash, mf->v2, mf->v3))
                                                mark= 1;
-                               if(!(tf->unwrap & TF_SEAM3)) {
-                                       if(mf->v4) {
+                               if(mf->v4) {
+                                       if(!BLI_edgehash_haskey(seamhash, mf->v3, mf->v4))
                                                if(BLI_edgehash_haskey(ehash, mf->v3, mf->v4))
                                                        mark= 1;
-                                       }
-                                       else if(BLI_edgehash_haskey(ehash, mf->v3, mf->v1))
-                                               mark= 1;
+                                       if(!BLI_edgehash_haskey(seamhash, mf->v4, mf->v1))
+                                               if(BLI_edgehash_haskey(ehash, mf->v4, mf->v1))
+                                                       mark= 1;
                                }
-                               if(mf->v4 && !(tf->unwrap & TF_SEAM4))
-                                       if(BLI_edgehash_haskey(ehash, mf->v4, mf->v1))
-                                               mark= 1;
+                               else if(!BLI_edgehash_haskey(seamhash, mf->v3, mf->v1))
+                                       if(BLI_edgehash_haskey(ehash, mf->v3, mf->v1))
+                                               mark = 1;
 
                                if(mark) {
                                        linkflag[a]= 1;
@@ -1317,6 +157,9 @@ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
                
        }
 
+       BLI_edgehash_free(ehash, NULL);
+       BLI_edgehash_free(seamhash, NULL);
+
        if(mode==0 || mode==2) {
                for(a=0, tf=me->tface; a<me->totface; a++, tf++)
                        if(linkflag[a])
@@ -1341,7 +184,6 @@ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
                }
        }
        
-       BLI_edgehash_free(ehash, NULL);
        MEM_freeN(linkflag);
        
        BIF_undo_push("Select linked UV face");
@@ -1350,7 +192,7 @@ void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
 
 /* Parametrizer */
 
-ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill)
+ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill, short sel)
 {
        int a;
        TFace *tf;
@@ -1371,7 +213,10 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill)
                float *uv[4];
                int nverts;
 
-               if ((tf->flag & TF_HIDE) || !(tf->flag & TF_SELECT))
+               if (tf->flag & TF_HIDE)
+                       continue;
+
+               if (sel && !(tf->flag & TF_SELECT))
                        continue;
 
                if (implicit && !(tf->flag & (TF_SEL1|TF_SEL2|TF_SEL3|TF_SEL4)))
@@ -1429,7 +274,7 @@ ParamHandle *construct_param_handle(Mesh *me, short implicit, short fill)
        return handle;
 }
 
-void unwrap_lscm_new(void)
+void unwrap_lscm(short seamcut)
 {
        Mesh *me;
        ParamHandle *handle;
@@ -1439,7 +284,7 @@ void unwrap_lscm_new(void)
        me= get_mesh(OBACT);
        if(me==0 || me->tface==0) return;
 
-       handle = construct_param_handle(me, 0, fillholes);
+       handle = construct_param_handle(me, 0, fillholes, seamcut == 0);
 
        param_lscm_begin(handle, PARAM_FALSE, abf);
        param_lscm_solve(handle);
@@ -1451,7 +296,8 @@ void unwrap_lscm_new(void)
 
        param_delete(handle);
 
-       BIF_undo_push("UV unwrap");
+       if (!seamcut)
+               BIF_undo_push("UV unwrap");
 
        object_uvs_changed(OBACT);
 
@@ -1471,7 +317,7 @@ void minimize_stretch_tface_uv(void)
        me = get_mesh(OBACT);
        if(me==0 || me->tface==0) return;
 
-       handle = construct_param_handle(me, 1, fillholes);
+       handle = construct_param_handle(me, 1, fillholes, 1);
 
        lasttime = PIL_check_seconds_timer();
 
@@ -1561,7 +407,7 @@ void smooth_area_tface_uv(void)
        me = get_mesh(OBACT);
        if(me==0 || me->tface==0) return;
 
-       handle = construct_param_handle(me, 1, fillholes);
+       handle = construct_param_handle(me, 1, fillholes, 1);
        param_smooth_area(handle);
        param_flush(handle);
        param_delete(handle);
@@ -1584,24 +430,16 @@ void unwrap_lscm_live_begin(void)
        short abf = G.scene->toolsettings->unwrapper == 1;
        short fillholes = G.scene->toolsettings->uvcalc_flag & 1;
 
-       if (G.scene->toolsettings->unwrapper == 2)
-               return;
-       
        me= get_mesh(OBACT);
        if(me==0 || me->tface==0) return;
 
-       liveHandle = construct_param_handle(me, 0, fillholes);
+       liveHandle = construct_param_handle(me, 0, fillholes, 1);
 
        param_lscm_begin(liveHandle, PARAM_TRUE, abf);
 }
 
 void unwrap_lscm_live_re_solve(void)
 {
-       if (G.scene->toolsettings->unwrapper == 2) {
-               unwrap_lscm();
-               return;
-       }
-
        if (liveHandle) {
                param_lscm_solve(liveHandle);
                param_flush(liveHandle);
@@ -1610,9 +448,6 @@ void unwrap_lscm_live_re_solve(void)
        
 void unwrap_lscm_live_end(short cancel)
 {
-       if (G.scene->toolsettings->unwrapper == 2)
-               return;
-
        if (liveHandle) {
                param_lscm_end(liveHandle);
                if (cancel)
index 38703ef322f540942659e307d40a8be299e34b60..b33495fad90b07a2f3b5fc3876ae201bab28e956 100644 (file)
@@ -571,6 +571,8 @@ void viewmove(int mode)
                        VECCOPY(obofs, ofs);
                }
        }
+       else
+               ofs[0] = ofs[1] = ofs[2] = 0.0f;
 
        reverse= 1.0f;
        if (G.vd->persmat[2][1] < 0.0f)
index 749f45d772e010aedfb15261edffae4f5940f429..d6533fbe12f34b3f4a14aadc200971d6c53c2cb9 100644 (file)
@@ -652,26 +652,6 @@ static int sample_backbuf_area(int x, int y, float size)
        return tot;
 }
 
-static unsigned int sample_backbuf(int x, int y)
-{
-       unsigned int col;
-       
-       if(x>=curarea->winx || y>=curarea->winy) return 0;
-       
-       x+= curarea->winrct.xmin;
-       y+= curarea->winrct.ymin;
-
-#ifdef __APPLE__
-       glReadBuffer(GL_AUX0);
-#endif
-       glReadPixels(x,  y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,  &col);
-       glReadBuffer(GL_BACK);  
-
-       if(G.order==B_ENDIAN) SWITCH_INT(col);
-               
-       return framebuffer_to_index(col);
-}
-
 static int calc_vp_alpha_dl(VPaint *vp, float *vert_nor, short *mval)
 {
        float fac, dx, dy;