Big commit, had to rework lots of selection stuff so that things
authorDaniel Dunbar <daniel@zuster.org>
Tue, 9 Aug 2005 08:12:36 +0000 (08:12 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 9 Aug 2005 08:12:36 +0000 (08:12 +0000)
worked properly with modifiers. Needs more testing I am sure.
No, honestly, I wasn't just cleaning for the hell of it, it
was *necessary* (I would never do such a thing). Selection should
work completely with cage options of modifiers now.

 - added DerivedMesh foreach functions to iterate over mapped
   verts/edges/face centers. These replaced some of the drawing
   functions and are more general anyway. Special edge drawing
   functions remain for performance reasons.
 - removed EditFace xs, ys fields
 - added general functions to iterate over screen coordinates of
   mesh/curve/lattice objects
 - removed all calc_*verts* functions that were used for storing
   screen coordinates in objects. they were recalc'd on the fly
   for most situations anyway, so now we just always do that.
   calc_*verts_ext was one of those calls that did dirty things
   deep down in the callstack (changing curarea and poking at
   matrices)
 - rewrote all vertex level selection routines (circle, lasso, bbox)
   and closest vertex routines (rightmouse select) to use the new
   system. This cleaned up the selection code a lot and the structure
   of selection is much easier to see now. This is good for future
   work on allowing modifiers to completely override the selection
   system. It also points out some discrepancies in the way selection
   is handled that might be nice to resolve (mesh vertex selection has
   fancy stuff to try to help with selecting overlapping, but it only
   works w/o bbuf select, and curves/lattices don't have at all).
 - had to remove ton's code to move Manipulator to cage location, this
   is not reliable (can come up with a different method if requested)
 - as it happens BezTriple.s and BPoint.s are basically available to
   be removed, just need to rewrite editipo code that still does
   background calc of screen coordinates
 - MVert.{xs,ys} are still around because they are abused in some places
   for other info (not sure if this is safe actually, since they are
   short's and the mvert limit went up).

And did I mention this commit is comes out to -305 lines? Well it does.

19 files changed:
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenlib/BLI_editVert.h
source/blender/include/BDR_drawobject.h
source/blender/include/BDR_editcurve.h
source/blender/include/BIF_editmesh.h
source/blender/python/api2_2x/BezTriple.c
source/blender/python/api2_2x/CurNurb.c
source/blender/src/buttons_editing.c
source/blender/src/drawobject.c
source/blender/src/editcurve.c
source/blender/src/editlattice.c
source/blender/src/editmesh_add.c
source/blender/src/editmesh_loop.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/editview.c
source/blender/src/transform_manipulator.c

index 1158f89dde09eb95fff6da7a9fd8a1d303d1911f..f4302d12bf6bb5238d9e13f4710f90bf276d4980 100644 (file)
@@ -63,7 +63,24 @@ struct DerivedMesh {
                /* Also called in Editmode */
        int (*getNumFaces)(DerivedMesh *dm);
 
-       void (*getMappedVertCoEM)(DerivedMesh *dm, void *vert, float co_r[3]);
+               /* Iterate over each mapped vertex in the derived mesh, calling the
+                * given function with the original vert and the mapped vert's new
+                * coordinate and normal. For historical reasons the normal can be
+                * passed as a float or short array, only one should be non-NULL.
+                */
+       void (*foreachMappedVertEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditVert *vert, float *co, float *no_f, short *no_s), void *userData);
+
+               /* Iterate over each mapped vertex in the derived mesh, calling the
+                * given function with the original vert and the mapped edge's new
+                * coordinates.
+                */
+       void (*foreachMappedEdgeEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditEdge *edge, float *v0co, float *v1co), void *userData);
+
+               /* Iterate over each mapped face in the derived mesh, calling the
+                * given function with the original face and the mapped face's (or
+                * faces') center and normal.
+                */
+       void (*foreachMappedFaceCenterEM)(DerivedMesh *dm, void (*func)(void *userData, struct EditFace *face, float *cent, float *no), void *userData);
 
                /* Convert to new DispListMesh, should be free'd by caller.
                 *
@@ -144,11 +161,6 @@ struct DerivedMesh {
                         */
        void (*drawFacesTex)(DerivedMesh *dm, int (*setDrawParams)(TFace *tf, int matnr));
 
-                       /* Draw mapped vertices as bgl points
-                        *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-vert) returns true
-                        */
-       void (*drawMappedVertsEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData);
-
                        /* Draw mapped edges as lines
                         *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-edge) returns true
                         */
@@ -169,21 +181,6 @@ struct DerivedMesh {
                         */
        void (*drawMappedFacesEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData);
 
-                       /* Draw vert normals
-                        *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-vert) returns true
-                        */
-        void (*drawMappedVertNormalsEM)(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData);
-
-                       /* Draw face normals
-                        *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-face) returns true
-                        */
-       void (*drawMappedFaceNormalsEM)(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData);
-
-                       /* Draw face centers as bgl points
-                        *  o Only if !setDrawOptions or setDrawOptions(userData, mapped-face) returns true
-                        */
-       void (*drawMappedFaceCentersEM)(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData);
-
        void (*release)(DerivedMesh *dm);
 };
 
index 25ec8d6e3a49385077755d2c413f0559d229d299..45d5669ebbadf7c28a4bc623687fed4923e94a23 100644 (file)
@@ -504,47 +504,41 @@ typedef struct {
        float (*faceNos)[3];
 } EditMeshDerivedMesh;
 
-static void emDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
+static void emDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData)
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
+       EditVert *eve;
 
        if (emdm->vertexCos) {
-               EditVert *eve;
                int i;
 
                for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
-                       if (eve==vert) {
-                               VECCOPY(co_r, emdm->vertexCos[i]);
-                               break;
-                       }
+                       func(userData, eve, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
                }
        } else {
-               EditVert *eve = vert;
-
-               VECCOPY(co_r, eve->co);
+               for (eve= emdm->em->verts.first; eve; eve=eve->next) {
+                       func(userData, eve, eve->co, eve->no, NULL);
+               }
        }
 }
-static void emDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData)
+static void emDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData)
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve;
+       EditEdge *eed;
 
        if (emdm->vertexCos) {
+               EditVert *eve, *preveve;
                int i;
 
-               bglBegin(GL_POINTS);
-               for(i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
-                       if(!setDrawOptions || setDrawOptions(userData, eve))
-                               bglVertex3fv(emdm->vertexCos[i]);
-               }
-               bglEnd();               
+               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
+                       eve->prev = (EditVert*) i++;
+               for(eed= emdm->em->edges.first; eed; eed= eed->next)
+                       func(userData, eed, emdm->vertexCos[(int) eed->v1->prev], emdm->vertexCos[(int) eed->v2->prev]);
+               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
+                       eve->prev = preveve;
        } else {
-               bglBegin(GL_POINTS);
-               for(eve= emdm->em->verts.first; eve; eve= eve->next) {
-                       if(!setDrawOptions || setDrawOptions(userData, eve))
-                               bglVertex3fv(eve->co);
-               }
-               bglEnd();               
+               for(eed= emdm->em->edges.first; eed; eed= eed->next)
+                       func(userData, eed, eed->v1->co, eed->v2->co);
        }
 }
 static void emDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) 
@@ -643,7 +637,7 @@ static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[
                VecMulf(cent, 0.33333333333f);
        }
 }
-static void emDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
+static void emDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData)
 {
        EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
        EditVert *eve, *preveve;
@@ -656,78 +650,16 @@ static void emDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(
                        eve->prev = (EditVert*) i++;
        }
 
-       bglBegin(GL_POINTS);
        for(efa= emdm->em->faces.first; efa; efa= efa->next) {
-               if(!setDrawOptions || setDrawOptions(userData, efa)) {
-                       emDM__calcFaceCent(efa, cent, emdm->vertexCos);
-                       bglVertex3fv(cent);
-               }
-       }
-       bglEnd();
-
-       if (emdm->vertexCos) {
-               for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
-                       eve->prev = preveve;
-       }
-}
-static void emDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve, *preveve;
-       EditFace *efa;
-       float cent[3];
-       int i;
-
-       glBegin(GL_LINES);
-       if (emdm->vertexCos) {
-               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->prev = (EditVert*) i++;
-       }
-
-
-       for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
-               if(!setDrawOptions || setDrawOptions(userData, efa)) {
-                       float *no = emdm->vertexCos?emdm->faceNos[i]:efa->n;
-
-                       emDM__calcFaceCent(efa, cent, emdm->vertexCos);
-
-                       glVertex3fv(cent);
-                       glVertex3f(     cent[0] + length*no[0],
-                                               cent[1] + length*no[1],
-                                               cent[2] + length*no[2]);
-               }
+               emDM__calcFaceCent(efa, cent, emdm->vertexCos);
+               func(userData, efa, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
+               bglVertex3fv(cent);
        }
 
        if (emdm->vertexCos) {
                for (preveve=NULL, eve=emdm->em->verts.first; eve; preveve=eve, eve= eve->next)
                        eve->prev = preveve;
        }
-
-       glEnd();
-}
-static void emDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve;
-       int i;
-
-       glBegin(GL_LINES);
-       for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
-               if(!setDrawOptions || setDrawOptions(userData, eve)) {
-                       if (emdm->vertexCos) {
-                               glVertex3fv(emdm->vertexCos[i]);
-                               glVertex3f(     emdm->vertexCos[i][0] + length*emdm->vertexNos[i][0],
-                                                       emdm->vertexCos[i][1] + length*emdm->vertexNos[i][1],
-                                                       emdm->vertexCos[i][2] + length*emdm->vertexNos[i][2]);
-                       } else {
-                               glVertex3fv(eve->co);
-                               glVertex3f(     eve->co[0] + length*eve->no[0],
-                                                       eve->co[1] + length*eve->no[1],
-                                                       eve->co[2] + length*eve->no[2]);
-                       }
-               }
-       }
-       glEnd();
 }
 static void emDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
 {
@@ -865,17 +797,13 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, float (*vertexCos)[3])
 
        emdm->dm.getNumVerts = emDM_getNumVerts;
        emdm->dm.getNumFaces = emDM_getNumFaces;
-       emdm->dm.getMappedVertCoEM = emDM_getMappedVertCoEM;
-
-       emdm->dm.drawMappedVertsEM = emDM_drawMappedVertsEM;
+       emdm->dm.foreachMappedVertEM = emDM_foreachMappedVertEM;
+       emdm->dm.foreachMappedEdgeEM = emDM_foreachMappedEdgeEM;
+       emdm->dm.foreachMappedFaceCenterEM = emDM_foreachMappedFaceCenterEM;
 
        emdm->dm.drawEdges = emDM_drawEdges;
        emdm->dm.drawMappedEdgesEM = emDM_drawMappedEdgesEM;
        emdm->dm.drawMappedEdgesInterpEM = emDM_drawMappedEdgesInterpEM;
-       
-       emdm->dm.drawMappedVertNormalsEM = emDM_drawMappedVertNormalsEM;
-       emdm->dm.drawMappedFaceNormalsEM = emDM_drawMappedFaceNormalsEM;
-       emdm->dm.drawMappedFaceCentersEM = emDM_drawMappedFaceCentersEM;
 
        emdm->dm.drawFacesSolid = emDM_drawFacesSolid;
        emdm->dm.drawMappedFacesEM = emDM_drawMappedFacesEM;
@@ -946,37 +874,34 @@ typedef struct {
        EditFace **faceMap;
 } SSDerivedMesh;
 
-static void ssDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3])
+static void ssDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData)
 {
        SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
        DispListMesh *dlm = ssdm->dlm;
+       int i;
 
        if (ssdm->vertMap) {
-               int i;
-
                for (i=0; i<dlm->totvert; i++) {
-                       if (ssdm->vertMap[i]==vert) {
-                               VECCOPY(co_r, dlm->mvert[i].co);
-                               break;
+                       if (ssdm->vertMap[i]) {
+                               func(userData, ssdm->vertMap[i], dlm->mvert[i].co, NULL, dlm->mvert[i].no);
                        }
                }
        }
 }
-static void ssDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData)
+static void ssDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData)
 {
        SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
        DispListMesh *dlm = ssdm->dlm;
+       int i;
 
-       if (ssdm->vertMap) {
-               int i;
+       if (ssdm->edgeMap) {
+               for (i=0; i<dlm->totedge; i++) {
+                       if (ssdm->edgeMap[i]) {
+                               MEdge *med = &dlm->medge[i];
 
-               bglBegin(GL_POINTS);
-               for (i=0; i<dlm->totvert; i++) {
-                       if(ssdm->vertMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->vertMap[i]))) {
-                               bglVertex3fv(dlm->mvert[i].co);
+                               func(userData, ssdm->edgeMap[i], dlm->mvert[med->v1].co, dlm->mvert[med->v2].co);
                        }
                }
-               bglEnd();
        }
 }
 static void ssDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) 
@@ -999,49 +924,15 @@ static void ssDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *
        }
 }
 
-static void ssDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-
-       if (ssdm->faceMap) {
-               bglBegin(GL_POINTS);
-               for (i=0; i<dlm->totface; i++) {
-                       if(ssdm->faceMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->faceMap[i]))) {
-                               MFace *mf = &dlm->mface[i];
-
-                               if (mf->v3) {
-                                       float cent[3];
-
-                                       VECCOPY(cent, dlm->mvert[mf->v1].co);
-                                       VecAddf(cent, cent, dlm->mvert[mf->v2].co);
-                                       VecAddf(cent, cent, dlm->mvert[mf->v3].co);
-
-                                       if (mf->v4) {
-                                               VecAddf(cent, cent, dlm->mvert[mf->v4].co);
-                                               VecMulf(cent, 0.25f);
-                                       } else {
-                                               VecMulf(cent, 0.33333333333f);
-                                       }
-
-                                       bglVertex3fv(cent);
-                               }
-                       }
-               }
-               bglEnd();
-       }
-}
-static void ssDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData)
+static void ssDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData)
 {
        SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
        DispListMesh *dlm = ssdm->dlm;
        int i;
 
        if (ssdm->faceMap) {
-               glBegin(GL_LINES);
                for (i=0; i<dlm->totface; i++) {
-                       if(ssdm->faceMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->faceMap[i]))) {
+                       if(ssdm->faceMap[i]) {
                                MFace *mf = &dlm->mface[i];
 
                                if (mf->v3) {
@@ -1061,36 +952,10 @@ static void ssDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*se
                                                VecMulf(cent, 0.33333333333f);
                                        }
 
-                                       glVertex3fv(cent);
-                                       glVertex3f(     cent[0] + length*no[0],
-                                                               cent[1] + length*no[1],
-                                                               cent[2] + length*no[2]);
+                                       func(userData, ssdm->faceMap[i], cent, no);
                                }
                        }
                }
-               glEnd();
-       }
-}
-static void ssDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData)
-{
-       SSDerivedMesh *ssdm = (SSDerivedMesh*) dm;
-       DispListMesh *dlm = ssdm->dlm;
-       int i;
-
-       if (ssdm->vertMap) {
-               glBegin(GL_LINES);
-               for (i=0; i<dlm->totvert; i++) {
-                       if(ssdm->vertMap[i] && (!setDrawOptions || setDrawOptions(userData, ssdm->vertMap[i]))) {
-                               float *co = dlm->mvert[i].co;
-                               short *no = dlm->mvert[i].no;
-
-                               glVertex3fv(co);
-                               glVertex3f(     co[0] + length*no[0]/32767.0,
-                                                       co[1] + length*no[1]/32767.0,
-                                                       co[2] + length*no[2]/32767.0);
-                       }
-               }
-               glEnd();
        }
 }
 static void ssDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditFace *face), void *userData)
@@ -1459,16 +1324,13 @@ DerivedMesh *derivedmesh_from_displistmesh(DispListMesh *dlm, float (*vertexCos)
 
                /* EM functions */
        
-       ssdm->dm.getMappedVertCoEM = ssDM_getMappedVertCoEM;
-       ssdm->dm.drawMappedVertsEM = ssDM_drawMappedVertsEM;
-
+       ssdm->dm.foreachMappedVertEM = ssDM_foreachMappedVertEM;
+       ssdm->dm.foreachMappedEdgeEM = ssDM_foreachMappedEdgeEM;
+       ssdm->dm.foreachMappedFaceCenterEM = ssDM_foreachMappedFaceCenterEM;
+       
        ssdm->dm.drawMappedEdgesEM = ssDM_drawMappedEdgesEM;
        ssdm->dm.drawMappedEdgesInterpEM = NULL; // no way to implement this one
        
-       ssdm->dm.drawMappedVertNormalsEM = ssDM_drawMappedVertNormalsEM;
-       ssdm->dm.drawMappedFaceNormalsEM = ssDM_drawMappedFaceNormalsEM;
-       ssdm->dm.drawMappedFaceCentersEM = ssDM_drawMappedFaceCentersEM;
-
        ssdm->dm.drawMappedFacesEM = ssDM_drawMappedFacesEM;
 
        ssdm->dm.release = ssDM_release;
index d75b6c31d9142b9cec4f7e7662ee8751f8de9e4e..8feeb649854631ee7d370b27a1f7a8f841aa67d8 100644 (file)
@@ -751,39 +751,35 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
        }
        ccgFaceIterator_free(fi);
 }
-static void ccgDM_getMappedVertCoEM(DerivedMesh *dm, void *vert, float co_r[3]) {
+static void ccgDM_foreachMappedVertEM(DerivedMesh *dm, void (*func)(void *userData, EditVert *vert, float *co, float *no_f, short *no_s), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
 
-               /* The vert handle is an index into the vmap in this case, have
-                * to search for it.
-                */
-       if (ccgdm->vertMap) {
-               CCGVertIterator *vi = ccgSubSurf_getVertIterator(ccgdm->ss);
-
-               for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
-                       CCGVert *v = ccgVertIterator_getCurrent(vi);
-                       int index = (int) ccgSubSurf_getVertVertHandle(ccgdm->ss, v);
-
-                       if (ccgdm->vertMap[index]==vert) {
-                               float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
+       for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
+               CCGVert *v = ccgVertIterator_getCurrent(vi);
+               VertData *vd = ccgSubSurf_getVertData(ccgdm->ss, v);
 
-                               co_r[0] = co[0];
-                               co_r[1] = co[1];
-                               co_r[2] = co[2];
+               func(userData, ccgDM_getVertHandle(ccgdm, v), vd->co, vd->no, NULL);
+       }
 
-                               break;
-                       }
-               }
+       ccgVertIterator_free(vi);
+}
+static void ccgDM_foreachMappedEdgeEM(DerivedMesh *dm, void (*func)(void *userData, EditEdge *eed, float *v0co, float *v1co), void *userData) {
+       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
+       CCGSubSurf *ss = ccgdm->ss;
+       CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss);
+       int i, edgeSize = ccgSubSurf_getEdgeSize(ss);
 
-               ccgVertIterator_free(vi);
-       } else {
-               CCGVert *v = ccgSubSurf_getVert(ccgdm->ss, vert);
-               float *co = ccgSubSurf_getVertData(ccgdm->ss, v);
+       for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) {
+               CCGEdge *e = ccgEdgeIterator_getCurrent(ei);
+               EditEdge *edge = ccgDM_getEdgeHandle(ccgdm, e);
+               VertData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e);
 
-               co_r[0] = co[0];
-               co_r[1] = co[1];
-               co_r[2] = co[2];
+               for (i=0; i<edgeSize-1; i++)
+                       func(userData, edge, edgeData[i].co, edgeData[i+1].co);
        }
+
+       ccgEdgeIterator_free(ei);
 }
 static DispListMesh *ccgDM_convertToDispListMesh(DerivedMesh *dm, int allowShared) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
@@ -1216,47 +1212,6 @@ static void ccgDM_drawFacesTex(DerivedMesh *dm, int (*setDrawParams)(TFace *tf,
 */
 }
 
-static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditVert *vert), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
-       CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
-
-       bglBegin(GL_POINTS);
-       for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
-               CCGVert *v = ccgVertIterator_getCurrent(vi);
-               EditVert *vert = ccgDM_getVertHandle(ccgdm, v);
-
-               if (vert && (!setDrawOptions || setDrawOptions(userData, vert))) {
-                       bglVertex3fv(ccgSubSurf_getVertData(ss, v));
-               }
-       }
-       bglEnd();
-
-       ccgVertIterator_free(vi);
-}
-static void ccgDM_drawMappedVertNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditVert *eve), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
-       CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss);
-
-       glBegin(GL_LINES);
-       for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) {
-               CCGVert *v = ccgVertIterator_getCurrent(vi);
-               EditVert *vert = ccgDM_getVertHandle(ccgdm, v);
-
-               if (vert && (!setDrawOptions || setDrawOptions(userData, vert))) {
-                       VertData *vd = ccgSubSurf_getVertData(ss, v);
-
-                       glVertex3fv(vd->co);
-                       glVertex3f(     vd->co[0] + length*vd->no[0],
-                                               vd->co[1] + length*vd->no[1],
-                                               vd->co[2] + length*vd->no[2]);
-               }
-       }
-       glEnd();
-
-       ccgVertIterator_free(vi);
-}
 static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, EditEdge *edge), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
@@ -1345,47 +1300,23 @@ static void ccgDM_drawMappedFacesEM(DerivedMesh *dm, int (*setDrawOptions)(void
 
        ccgFaceIterator_free(fi);
 }
-static void ccgDM_drawMappedFaceNormalsEM(DerivedMesh *dm, float length, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData) {
+static void ccgDM_foreachMappedFaceCenterEM(DerivedMesh *dm, void (*func)(void *userData, EditFace *efa, float *co, float *no), void *userData) {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
        CCGSubSurf *ss = ccgdm->ss;
        CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
        int gridSize = ccgSubSurf_getGridSize(ss);
 
-       glBegin(GL_LINES);
        for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
                CCGFace *f = ccgFaceIterator_getCurrent(fi);
                EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
-               if (efa && (!setDrawOptions || setDrawOptions(userData, efa))) {
+
+               if (efa) {
                                /* Face center data normal isn't updated atm. */
                        VertData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0);
 
-                       glVertex3fv(vd->co);
-                       glVertex3f(     vd->co[0] + length*vd->no[0],
-                                               vd->co[1] + length*vd->no[1],
-                                               vd->co[2] + length*vd->no[2]);
-               }
-       }
-       glEnd();
-
-       ccgFaceIterator_free(fi);
-}
-static void ccgDM_drawMappedFaceCentersEM(DerivedMesh *dm, int (*setDrawOptions)(void *userData, struct EditFace *efa), void *userData) {
-       CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
-       CCGSubSurf *ss = ccgdm->ss;
-       CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss);
-       int gridSize = ccgSubSurf_getGridSize(ss);
-
-       bglBegin(GL_POINTS);
-       for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) {
-               CCGFace *f = ccgFaceIterator_getCurrent(fi);
-               EditFace *efa = ccgDM_getFaceHandle(ccgdm, f);
-               if (efa && (!setDrawOptions || setDrawOptions(userData, efa))) {
-                       VertData *vd = ccgSubSurf_getFaceCenterData(ss, f);
-
-                       bglVertex3fv(vd->co);
+                       func(userData, efa, vd->co, vd->no);
                }
        }
-       bglEnd();
 
        ccgFaceIterator_free(fi);
 }
@@ -1410,7 +1341,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh
        ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
        ccgdm->dm.getNumFaces = ccgDM_getNumFaces;
        ccgdm->dm.getVertCos = ccgdm_getVertCos;
-       ccgdm->dm.getMappedVertCoEM = ccgDM_getMappedVertCoEM;
+       ccgdm->dm.foreachMappedVertEM = ccgDM_foreachMappedVertEM;
+       ccgdm->dm.foreachMappedEdgeEM = ccgDM_foreachMappedEdgeEM;
+       ccgdm->dm.foreachMappedFaceCenterEM = ccgDM_foreachMappedFaceCenterEM;
        ccgdm->dm.convertToDispListMesh = ccgDM_convertToDispListMesh;
        ccgdm->dm.convertToDispListMeshMapped = ccgDM_convertToDispListMeshMapped;
 
@@ -1422,13 +1355,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int fromEditmesh, Mesh
        ccgdm->dm.drawFacesColored = ccgDM_drawFacesColored;
        ccgdm->dm.drawFacesTex = ccgDM_drawFacesTex;
 
-       ccgdm->dm.drawMappedVertsEM = ccgDM_drawMappedVertsEM;
-       ccgdm->dm.drawMappedVertNormalsEM = ccgDM_drawMappedVertNormalsEM;
        ccgdm->dm.drawMappedEdgesInterpEM = ccgDM_drawMappedEdgesInterpEM;
        ccgdm->dm.drawMappedEdgesEM = ccgDM_drawMappedEdgesEM;
        ccgdm->dm.drawMappedFacesEM = ccgDM_drawMappedFacesEM;
-       ccgdm->dm.drawMappedFaceNormalsEM = ccgDM_drawMappedFaceNormalsEM;
-       ccgdm->dm.drawMappedFaceCentersEM = ccgDM_drawMappedFaceCentersEM;
 
        ccgdm->dm.release = ccgDM_release;
        
index 6263a35432d39a2105a9a6369d77b7fff169fbb8..5e393570e94e6e4130a6e5af8244fee71734bd80 100644 (file)
@@ -82,7 +82,6 @@ typedef struct EditFace
        struct EditVert *v1, *v2, *v3, *v4;
        struct EditEdge *e1, *e2, *e3, *e4;
        float n[3], cent[3];
-       short xs, ys;           /* selection */
        struct TFace tf;        /* a copy of original tface. */
        unsigned char mat_nr, flag;
        unsigned char f, f1, h;
index 02b12582b2a7f114d229c78962abe89527b3366d..96457376924312f3d27bfb7a7c1dce74a7c3ab64 100644 (file)
@@ -44,16 +44,21 @@ struct Lamp;
 struct ListBase;
 struct BoundBox;
 struct Base;
+struct BPoint;
+struct BezTriple;
+struct EditVert;
 
 void init_draw_rects(void);
 void drawaxes(float size);
 void drawcamera(struct Object *ob);
 
-void calc_mesh_facedots_ext(void);
-void calc_lattverts_ext(void);
-void calc_meshverts_ext(void);
-void calc_meshverts_ext_f2(void);
-void calc_nurbverts_ext(void);
+void mesh_foreachScreenVert(void (*func)(void *userData, struct EditVert *eve, int x, int y, int index), void *userData, int clipVerts);
+void mesh_foreachScreenEdge(void (*func)(void *userData, struct EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts);
+void mesh_foreachScreenFace(void (*func)(void *userData, struct EditFace *efa, int x, int y, int index), void *userData);
+
+void lattice_foreachScreenVert(void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData);
+void nurbs_foreachScreenVert(void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData);
+
 void drawcircball(int mode, float *cent, float rad, float tmat[][4]);
 void get_local_bounds(struct Object *ob, float *centre, float *size);
 void draw_object(struct Base *base);
index 461eaa813183be55fb0bd525c4f6f902d58de527..1abf2dbe867c968726690ceeb9ed075b61a11b07 100644 (file)
@@ -62,10 +62,6 @@ void hideNurb(int swap);
 void revealNurb(void);
 void selectswapNurb(void);
 void subdivideNurb(void);
-short findnearestNurbvert(short sel, struct Nurb **nurb, 
-                                                 struct BezTriple **bezt, struct BPoint **bp);
-void findselectedNurbvert(struct Nurb **nu, struct BezTriple **bezt, 
-                                                 struct BPoint **bp);
 
 int convertspline(short type, struct Nurb *nu);
 void setsplinetype(short type);
index c92449ddea75524d54eff8754d77f5b9e4a680e6..b110643e6666bcf1c5f808d9d0e8667e0f8f5a9e 100644 (file)
@@ -96,8 +96,8 @@ extern void EM_select_face_fgon(struct EditFace *efa, int sel);
 extern int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax);
 extern int EM_mask_init_backbuf_border(short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax);
 extern int EM_init_backbuf_circle(short xs, short ys, short rads);
-extern int EM_check_backbuf_border(unsigned int index);
-extern void EM_free_backbuf_border(void);
+extern int EM_check_backbuf(unsigned int index);
+extern void EM_free_backbuf(void);
 
 extern void EM_selectmode_menu(void);
 
index 2e97bd2910e4b5abe629fe630d6b67fc1e527fb2..1fd736a1bc6fecfa52df3c36b708503a99216144 100644 (file)
@@ -331,15 +331,12 @@ static PyObject *BezTripleRepr( BPy_BezTriple * self )
         */
        char str[1000];
        sprintf( str,
-                "BezTriple %f %f %f %f %f %f %f %f %f %f\n %d %d %d %d %d %d %d %d %d %d %d %d\n",
+                "BezTriple %f %f %f %f %f %f %f %f %f %f\n %d %d %d %d %d %d\n",
                 self->beztriple->vec[0][0], self->beztriple->vec[0][1],
                 self->beztriple->vec[0][2], self->beztriple->vec[1][0],
                 self->beztriple->vec[1][1], self->beztriple->vec[1][2],
                 self->beztriple->vec[2][0], self->beztriple->vec[2][1],
                 self->beztriple->vec[2][2], self->beztriple->alfa,
-                self->beztriple->s[0][0], self->beztriple->s[0][1],
-                self->beztriple->s[1][0], self->beztriple->s[1][1],
-                self->beztriple->s[2][0], self->beztriple->s[1][1],
                 self->beztriple->h1, self->beztriple->h2, self->beztriple->f1,
                 self->beztriple->f2, self->beztriple->f3,
                 self->beztriple->hide );
@@ -359,14 +356,11 @@ static PyObject *BezTriple_Str( BPy_BezTriple * self )
 
 // fixme: 
        return PyString_FromFormat(
-                "BezTriple (%f %f %f) (%f %f %f) (%f %f %f) alpha %f\n (%d %d) (%d %d) (%d %d) h1:%d h2:%d f1:%d f2:%d f3:%d hide:%d",
+                "BezTriple (%f %f %f) (%f %f %f) (%f %f %f) alpha %f\n h1:%d h2:%d f1:%d f2:%d f3:%d hide:%d",
                 p->vec[0][0], p->vec[0][1],  p->vec[0][2], 
                 p->vec[1][0],  p->vec[1][1], p->vec[1][2],
                 p->vec[2][0], p->vec[2][1],  p->vec[2][2],
                 p->alfa,
-                p->s[0][0], p->s[0][1],
-                p->s[1][0], p->s[1][1],
-                p->s[2][0], p->s[1][1],
                 p->h1, p->h2, p->f1,
                 p->f2, p->f3,
                 p->hide );
index bb9fa25643b89b5b2f14f5bbd90e4ad4f7793587..5a86b50fd8d894b5926bc6c3c911b354da041ebe 100644 (file)
@@ -1025,8 +1025,7 @@ PyObject *CurNurb_dump( BPy_CurNurb * self )
                        }
                
                        /* alfa, s[2] */
-                       printf("\n alpha: %5.2f   s: %d %d ", 
-                                  bp->alfa, bp->s[0], bp->s[1] );
+                       printf("\n alpha: %5.2f", bp->alfa);
                        /* f1, hide */
                        printf(" f1 %d  hide %d", bp->f1, bp->hide );
                        printf("\n");
index fc1d71132ea2ab25117a372510c7065c8689322b..0f6c2fcf90962c59317102b40fab550df0df4958 100644 (file)
@@ -1781,7 +1781,6 @@ void do_latticebuts(unsigned short event)
                allqueue(REDRAWVIEW3D, 0);
                break;
        case B_DRAWLAT:
-               if(ob==G.obedit) calc_lattverts_ext();
                allqueue(REDRAWVIEW3D, 0);
                break;
        case B_LATTCHANGED:
index 280165fb6d5fe4d7b6cb47b66a40aaeb7518baac..02b90877b6ce3fa932b297d4d2db2688f7e79a2f 100644 (file)
@@ -276,7 +276,7 @@ void init_draw_rects(void)
 
 static void draw_icon_centered(float *pos, unsigned int *rect, int rectsize) 
 {
-       float hsize= (float) rectsize/2.0;
+       float hsize= (float) rectsize/2.0f;
        GLubyte dummy= 0;
        
        glRasterPos3fv(pos);
@@ -836,36 +836,29 @@ static void tekenvertslatt(short sel)
        bglEnd();       
 }
 
-static void calc_lattverts(void)
+void lattice_foreachScreenVert(void (*func)(void *userData, BPoint *bp, int x, int y), void *userData)
 {
-       BPoint *bp;
+       int i, N = editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
        float mat[4][4];
-       int a;
+       short s[2];
 
+       areawinset(curarea->win);
+       persp(PERSP_VIEW);
+       mymultmatrix(G.obedit->obmat);
        MTC_Mat4SwapMat4(G.vd->persmat, mat);
        mygetsingmatrix(G.vd->persmat);
-       
-        bp= editLatt->def;
-       
-       a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
-       while(a--) {
-               project_short(bp->vec, bp->s);
-               bp++;
-       }
-
-       MTC_Mat4SwapMat4(G.vd->persmat, mat);
-}
 
+       for (i=0; i<N; i++) {
+               BPoint *bp = &editLatt->def[i];
 
-void calc_lattverts_ext(void)
-{
+               if (bp->hide==0) {
+                       project_short(bp->vec, s);
+                       func(userData, bp, s[0], s[1]);
+               }
+       }
 
-       areawinset(curarea->win);
-       persp(PERSP_VIEW);
-       mymultmatrix(G.obedit->obmat);
-       calc_lattverts();
+       MTC_Mat4SwapMat4(G.vd->persmat, mat);
        myloadmatrix(G.vd->viewmat);
-       
 }
 
 
@@ -962,9 +955,6 @@ static void drawlattice(Object *ob)
        }
        
        if(ob==G.obedit) {
-               
-               calc_lattverts();
-               
                if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
                
                tekenvertslatt(0);
@@ -978,65 +968,107 @@ static void drawlattice(Object *ob)
 
 /* ***************** ******************** */
 
-void calc_mesh_facedots_ext(void)
+static void mesh_foreachScreenVert__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
 {
-       EditMesh *em = G.editMesh;
-       EditFace *efa;
+       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; } *data = userData;
+       short s[2];
+
+       if (eve->h==0) {
+               if (data->clipVerts) {
+                       project_short(co, s);
+               } else {
+                       project_short_noclip(co, s);
+               }
+
+               data->func(data->userData, eve, s[0], s[1], (int) eve->prev);
+       }
+}
+void mesh_foreachScreenVert(void (*func)(void *userData, EditVert *eve, int x, int y, int index), void *userData, int clipVerts)
+{
+       struct { void (*func)(void *userData, EditVert *eve, int x, int y, int index); void *userData; int clipVerts; } data;
+       int dmNeedsFree;
+       DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
        float mat[4][4];
+       EditVert *eve, *preveve;
+       int index;
 
-       if(em->faces.first==NULL) return;
-       efa= em->faces.first;
+       data.func = func;
+       data.userData = userData;
+       data.clipVerts = clipVerts;
 
        areawinset(curarea->win);
        persp(PERSP_VIEW);
-       
        mymultmatrix(G.obedit->obmat);
-
        MTC_Mat4SwapMat4(G.vd->persmat, mat);
        mygetsingmatrix(G.vd->persmat);
 
-       efa= em->faces.first;
-       while(efa) {
-               if( efa->h==0) {
-                       project_short(efa->cent, &(efa->xs));
-               }
-               efa= efa->next;
-       }
-       MTC_Mat4SwapMat4(G.vd->persmat, mat);
+       for (index=0,eve=G.editMesh->verts.first; eve; index++,eve= eve->next)
+               eve->prev = (EditVert*) index;
+
+       dm->foreachMappedVertEM(dm, mesh_foreachScreenVert__mapFunc, &data);
 
+       for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next)
+               eve->prev = preveve;
+
+       MTC_Mat4SwapMat4(G.vd->persmat, mat);
        myloadmatrix(G.vd->viewmat);
+
+       if (dmNeedsFree) {
+               dm->release(dm);
+       }
 }
 
-/* window coord, assuming all matrices are set OK */
-static void calc_meshverts(DerivedMesh *dm)
+static void mesh_foreachScreenEdge__mapFunc(void *userData, EditEdge *eed, float *v0co, float *v1co)
 {
-       float co[3], mat[4][4];
-       EditVert *eve;
+       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; } *data = userData;
+       short s[2][2];
 
-       MTC_Mat4SwapMat4(G.vd->persmat, mat);
-       mygetsingmatrix(G.vd->persmat);
+       if (eed->h==0) {
+               if (data->clipVerts==1) {
+                       project_short(v0co, s[0]);
+                       project_short(v1co, s[1]);
+               } else {
+                       project_short_noclip(v0co, s[0]);
+                       project_short_noclip(v1co, s[1]);
 
-       for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
-               if(eve->h==0) {
-                       dm->getMappedVertCoEM(dm, eve, co);
-                       project_short(co, &(eve->xs));
+                       if (data->clipVerts==2) {
+                if (!(s[0][0]>=0 && s[0][1]>= 0 && s[0][0]<curarea->winx && s[0][1]<curarea->winy)) 
+                                       if (!(s[1][0]>=0 && s[1][1]>= 0 && s[1][0]<curarea->winx && s[1][1]<curarea->winy)) 
+                                               return;
+                       }
                }
-       }
 
-       MTC_Mat4SwapMat4(G.vd->persmat, mat);
+               data->func(data->userData, eed, s[0][0], s[0][1], s[1][0], s[1][1], (int) eed->prev);
+       }
 }
-
-/* window coord for current window, sets matrices temporal */
-void calc_meshverts_ext(void)
+void mesh_foreachScreenEdge(void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, int clipVerts)
 {
+       struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; int clipVerts; } data;
        int dmNeedsFree;
        DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
+       float mat[4][4];
+       EditEdge *eed, *preveed;
+       int index;
+
+       data.func = func;
+       data.userData = userData;
+       data.clipVerts = clipVerts;
 
        areawinset(curarea->win);
        persp(PERSP_VIEW);
-       
        mymultmatrix(G.obedit->obmat);
-       calc_meshverts(dm);
+       MTC_Mat4SwapMat4(G.vd->persmat, mat);
+       mygetsingmatrix(G.vd->persmat);
+
+       for (index=0,eed=G.editMesh->edges.first; eed; index++,eed= eed->next)
+               eed->prev = (EditEdge*) index;
+
+       dm->foreachMappedEdgeEM(dm, mesh_foreachScreenEdge__mapFunc, &data);
+
+       for (preveed=NULL, eed=G.editMesh->edges.first; eed; preveed=eed, eed= eed->next)
+               eed->prev = preveed;
+
+       MTC_Mat4SwapMat4(G.vd->persmat, mat);
        myloadmatrix(G.vd->viewmat);
 
        if (dmNeedsFree) {
@@ -1044,34 +1076,43 @@ void calc_meshverts_ext(void)
        }
 }
 
-/* window coord for current window, sets matrices temporal, sets (eve->f & 2) when not visible */
-void calc_meshverts_ext_f2(void)
+static void mesh_foreachScreenFace__mapFunc(void *userData, EditFace *efa, float *cent, float *no)
+{
+       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; } *data = userData;
+       short s[2];
+
+       if (efa && efa->fgonf!=EM_FGON) {
+               project_short(cent, s);
+
+               data->func(data->userData, efa, s[0], s[1], (int) efa->prev);
+       }
+}
+void mesh_foreachScreenFace(void (*func)(void *userData, EditFace *efa, int x, int y, int index), void *userData)
 {
+       struct { void (*func)(void *userData, EditFace *efa, int x, int y, int index); void *userData; } data;
        int dmNeedsFree;
        DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
-       float co[3], mat[4][4];
-       EditVert *eve;
+       float mat[4][4];
+       EditFace *efa, *prevefa;
+       int index = 0;
+
+       data.func = func;
+       data.userData = userData;
 
-       /* matrices */
        areawinset(curarea->win);
        persp(PERSP_VIEW);
        mymultmatrix(G.obedit->obmat);
-       
        MTC_Mat4SwapMat4(G.vd->persmat, mat);
        mygetsingmatrix(G.vd->persmat);
 
-       for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
-               eve->f &= ~2;
-               if(eve->h==0) {
-                       dm->getMappedVertCoEM(dm, eve, co);
-                       project_short_noclip(co, &(eve->xs));
-       
-                       if( eve->xs >= 0 && eve->ys >= 0 && eve->xs<curarea->winx && eve->ys<curarea->winy);
-                       else eve->f |= 2;
-               }
-       }
-       
-       /* restore */
+       for (index=0,efa=G.editMesh->faces.first; efa; index++,efa= efa->next)
+               efa->prev = (EditFace*) index;
+
+       dm->foreachMappedFaceCenterEM(dm, mesh_foreachScreenFace__mapFunc, &data);
+
+       for (prevefa=NULL, efa=G.editMesh->faces.first; efa; prevefa=efa, efa= efa->next)
+               efa->prev = prevefa;
+
        MTC_Mat4SwapMat4(G.vd->persmat, mat);
        myloadmatrix(G.vd->viewmat);
 
@@ -1080,53 +1121,48 @@ void calc_meshverts_ext_f2(void)
        }
 }
 
-
-static void calc_Nurbverts(Nurb *nurb)
+void nurbs_foreachScreenVert(void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), void *userData)
 {
-       Nurb *nu;
-       BezTriple *bezt;
-       BPoint *bp;
        float mat[4][4];
-       int a;
+       short s[2];
+       Nurb *nu;
+       int i;
 
+       areawinset(curarea->win);
+       persp(PERSP_VIEW);
+       mymultmatrix(G.obedit->obmat);
        MTC_Mat4SwapMat4(G.vd->persmat, mat);
        mygetsingmatrix(G.vd->persmat);
 
-       nu= nurb;
-       while(nu) {
-               if((nu->type & 7)==1) {
-                       bezt= nu->bezt;
-                       a= nu->pntsu;
-                       while(a--) {
-                               project_short(bezt->vec[0], bezt->s[0]);
-                               project_short(bezt->vec[1], bezt->s[1]);
-                               project_short(bezt->vec[2], bezt->s[2]);
-                               bezt++;
+       for (nu= editNurb.first; nu; nu=nu->next) {
+               if((nu->type & 7)==CU_BEZIER) {
+                       for (i=0; i<nu->pntsu; i++) {
+                               BezTriple *bezt = &nu->bezt[i];
+
+                               if(bezt->hide==0) {
+                                       project_short(bezt->vec[0], s);
+                                       func(userData, nu, NULL, bezt, 0, s[0], s[1]);
+                                       project_short(bezt->vec[1], s);
+                                       func(userData, nu, NULL, bezt, 1, s[0], s[1]);
+                                       project_short(bezt->vec[2], s);
+                                       func(userData, nu, NULL, bezt, 2, s[0], s[1]);
+                               }
                        }
                }
                else {
-                       bp= nu->bp;
-                       a= nu->pntsu*nu->pntsv;
-                       while(a--) {
-                               project_short(bp->vec, bp->s);
-                               bp++;
+                       for (i=0; i<nu->pntsu*nu->pntsv; i++) {
+                               BPoint *bp = &nu->bp[i];
+
+                               if(bp->hide==0) {
+                                       project_short(bp->vec, s);
+                                       func(userData, nu, bp, NULL, -1, s[0], s[1]);
+                               }
                        }
                }
-               nu= nu->next;
        }
 
        MTC_Mat4SwapMat4(G.vd->persmat, mat);
-}
-
-void calc_nurbverts_ext(void)
-{
-
-       areawinset(curarea->win);
-       persp(PERSP_VIEW);
-       mymultmatrix(G.obedit->obmat);
-       calc_Nurbverts(editNurb.first);
        myloadmatrix(G.vd->viewmat);
-       
 }
 
 ////
@@ -1205,40 +1241,72 @@ static unsigned char *calc_weightpaint_colors(Object *ob)
  * logic!!!
  */
 
-static int ef_nonhiddenAndFgon__setDrawOptions(void *userData, EditFace *efa)
+static void draw_dm_face_normals__mapFunc(void *userData, EditFace *efa, float *cent, float *no)
 {
-       if (userData) {
-               int sel = ((int) userData) - 1;
-               return (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel);
-       } else {
-               return (efa->h==0 && efa->fgonf!=EM_FGON);
+       if (efa->h==0 && efa->fgonf!=EM_FGON) {
+               glVertex3fv(cent);
+               glVertex3f(     cent[0] + no[0]*G.scene->editbutsize,
+                                       cent[1] + no[1]*G.scene->editbutsize,
+                                       cent[2] + no[2]*G.scene->editbutsize);
        }
 }
-static int ev_nonhidden__setDrawOptions(void *userData, EditVert *eve)
-{
-       return (eve->h==0);
-}
 static void draw_dm_face_normals(DerivedMesh *dm) {
-       dm->drawMappedFaceNormalsEM(dm, G.scene->editbutsize, ef_nonhiddenAndFgon__setDrawOptions, 0);
+       glBegin(GL_LINES);
+       dm->foreachMappedFaceCenterEM(dm, draw_dm_face_normals__mapFunc, 0);
+       glEnd();
+}
+
+static void draw_dm_face_centers__mapFunc(void *userData, EditFace *efa, float *cent, float *no)
+{
+       int sel = *((int*) userData);
+
+       if (efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
+               bglVertex3fv(cent);
+       }
 }
-static void draw_dm_face_centers(DerivedMesh *dm, int sel) {
-       dm->drawMappedFaceCentersEM(dm, ef_nonhiddenAndFgon__setDrawOptions, (void*) (sel+1));
+static void draw_dm_face_centers(DerivedMesh *dm, int sel)
+{
+       bglBegin(GL_POINTS);
+       dm->foreachMappedFaceCenterEM(dm, draw_dm_face_centers__mapFunc, &sel);
+       bglEnd();
 }
 
+static void draw_dm_vert_normals__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
+{
+       if (eve->h==0) {
+               glVertex3fv(co);
+
+               if (no_f) {
+                       glVertex3f(     co[0] + no_f[0]*G.scene->editbutsize,
+                                               co[1] + no_f[1]*G.scene->editbutsize,
+                                               co[2] + no_f[2]*G.scene->editbutsize);
+               } else {
+                       glVertex3f(     co[0] + no_s[0]*G.scene->editbutsize/32767.0f,
+                                               co[1] + no_s[1]*G.scene->editbutsize/32767.0f,
+                                               co[2] + no_s[2]*G.scene->editbutsize/32767.0f);
+               }
+       }
+}
 static void draw_dm_vert_normals(DerivedMesh *dm) {
-       dm->drawMappedVertNormalsEM(dm, G.scene->editbutsize, ev_nonhidden__setDrawOptions, 0);
+       glBegin(GL_LINES);
+       dm->foreachMappedVertEM(dm, draw_dm_vert_normals__mapFunc, NULL);
+       glEnd();
 }
 
        /* Draw verts with color set based on selection */
-static int draw_dm_verts__setDrawOptions(void *userData, EditVert *eve)
+static void draw_dm_verts__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
 {
        int sel = *((int*) userData);
 
-       return (eve->h==0 && (eve->f&SELECT)==sel);
+       if (eve->h==0 && (eve->f&SELECT)==sel) {
+               bglVertex3fv(co);
+       }
 }
 static void draw_dm_verts(DerivedMesh *dm, int sel)
 {
-       dm->drawMappedVertsEM(dm, draw_dm_verts__setDrawOptions, &sel);
+       bglBegin(GL_POINTS);
+       dm->foreachMappedVertEM(dm, draw_dm_verts__mapFunc, &sel);
+       bglEnd();
 }
 
        /* Draw edges with color set based on selection */
@@ -1671,7 +1739,6 @@ static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, Derived
        }
 
        if(ob==G.obedit) {
-               calc_meshverts(cageDM);
                draw_em_fancy_verts(em, cageDM);
 
                if(G.f & G_DRAWNORMALS) {
@@ -2736,8 +2803,6 @@ static void drawnurb(Object *ob, Nurb *nurb, int dt)
                }
        }
 
-       calc_Nurbverts(nurb);
-
        if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
        
        nu= nurb;
@@ -3833,13 +3898,11 @@ void draw_object_ext(Base *base)
 
 /* ***************** BACKBUF SEL (BBS) ********* */
 
-static int bbs_mesh_verts__setDrawOptions(void *userData, EditVert *eve)
+static void bbs_mesh_verts__mapFunc(void *userData, EditVert *eve, float *co, float *no_f, short *no_s)
 {
        if (eve->h==0) {
                set_framebuffer_index_color((int) eve->prev);
-               return 1;
-       } else {
-               return 0;
+               bglVertex3fv(co);
        }
 }
 static int bbs_mesh_verts(DerivedMesh *dm, int offset)
@@ -3850,7 +3913,9 @@ static int bbs_mesh_verts(DerivedMesh *dm, int offset)
                eve->prev = (EditVert*) offset++;
 
        glPointSize( BIF_GetThemeValuef(TH_VERTEX_SIZE) );
-       dm->drawMappedVertsEM(dm, bbs_mesh_verts__setDrawOptions, NULL);
+       bglBegin(GL_POINTS);
+       dm->foreachMappedVertEM(dm, bbs_mesh_verts__mapFunc, NULL);
+       bglEnd();
        glPointSize(1.0);
 
        for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next)
@@ -3892,13 +3957,12 @@ static int bbs_mesh_solid__setSolidDrawOptions(void *userData, EditFace *efa)
        }
 }
 
-int bbs_mesh_solid__setCenterDrawOptions(void *userData, EditFace *efa)
+static void bbs_mesh_solid__drawCenter(void *userData, EditFace *efa, float *cent, float *no)
 {
        if (efa->h==0 && efa->fgonf!=EM_FGON) {
                set_framebuffer_index_color((int) efa->prev);
-               return 1; 
-       } else {
-               return 0;
+
+               bglVertex3fv(cent);
        }
 }
 
@@ -3921,7 +3985,9 @@ static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol)
                if(G.scene->selectmode & SCE_SELECT_FACE) {
                        glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
                
-                       dm->drawMappedFaceCentersEM(dm, bbs_mesh_solid__setCenterDrawOptions, NULL);
+                       bglBegin(GL_POINTS);
+                       dm->foreachMappedFaceCenterEM(dm, bbs_mesh_solid__drawCenter, NULL);
+                       bglEnd();
                }
 
                for (prevefa= NULL, efa= G.editMesh->faces.first; efa; prevefa= efa, efa= efa->next)
index b1e61bbbef677f3b0855092f019e107197ef2ea4..6932d583ba823f1771a343f10ab850ede2b40fe7 100644 (file)
@@ -185,48 +185,35 @@ void printknots()
 }
 
 #if 0
-static void printweightsNurb(void)
+static void printweightsNurb__doPrint(void *userData, Nurb *nurb, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
-       Nurb *nu;
-       BPoint *bp;
-       int a;
        char str[30];
 
-       if(G.obedit==0) return;
+       if (bp && (bp->f1&1)) {
+               sprintf(str,"%2.2f", bp->vec[3]);
 
-       persp(PERSP_WIN);
+               cpack(0x737373);
+               glRasterPos2i(x-1, y-1);
+               BMF_DrawString(G.font, str);
 
-       glDrawBuffer(GL_FRONT); 
+               glRasterPos2i(x+1, y+1);
+               BMF_DrawString(G.font, str);
 
-       nu= editNurb.first;
-       while(nu) {
-               if((nu->type & 7)==CU_NURBS) {
-                       a= nu->pntsu*nu->pntsv;
-                       bp= nu->bp;
-                       while(a--) {
-                               if(bp->f1 & 1) {
-                                       if(bp->s[0]!= 3200) {
-                                               sprintf(str,"%2.2f", bp->vec[3]);
-
-                                               cpack(0x737373);
-                                               glRasterPos2i(bp->s[0]-1, bp->s[1]-1);
-                                               BMF_DrawString(G.font, str);
+               cpack(0xFFFFFF);
+               glRasterPos2i(x, y);
+               BMF_DrawString(G.font, str);
+       }
+}
+static void printweightsNurb(void)
+{
+       if(G.obedit==0) return;
 
-                                               glRasterPos2i(bp->s[0]+1, bp->s[1]+1);
-                                               BMF_DrawString(G.font, str);
+       persp(PERSP_WIN);
 
-                                               cpack(0xFFFFFF);
-                                               glRasterPos2i(bp->s[0], bp->s[1]);
-                                               BMF_DrawString(G.font, str);
-                                       }
-                               }
-                               bp++;
-                       }
-               }
-               nu= nu->next;
-       }
+       glDrawBuffer(GL_FRONT); 
+       nurbs_foreachScreenVert(printweightsNurb__doPrint, NULL);
+       glDrawBuffer(GL_BACK);
 
-       glDrawBuffer(GL_BACK); 
        persp(PERSP_VIEW);
 }
 #endif
@@ -1679,93 +1666,62 @@ void subdivideNurb()
 
 }
 
-
-short findnearestNurbvert(short sel, Nurb **nurb, BezTriple **bezt, BPoint **bp)
+static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
-       /* sel==1: selected gets a disadvantage */
-       /* in nurb and bezt or bp the nearest is written */
-       /* return 0 1 2: handlepunt */
-       Nurb *nu;
-       BezTriple *bezt1;
-       BPoint *bp1;
-       short dist= 100, temp, mval[2], a, hpoint=0;
+       struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; short dist, hpoint, select, mval[2]; } *data = userData;
 
-       *nurb= 0;
-       *bezt= 0;
-       *bp= 0;
-
-       /* do projection */
-       calc_nurbverts_ext();   /* drawobject.c */
-       
-       getmouseco_areawin(mval);
+       short flag;
+       short temp;
 
-       nu= editNurb.first;
-       while(nu) {
-               if((nu->type & 7)==CU_BEZIER) {
-                       bezt1= nu->bezt;
-                       a= nu->pntsu;
-                       while(a--) {
-                               if(bezt1->hide==0) {
-                                       temp= abs(mval[0]- bezt1->s[0][0])+ abs(mval[1]- bezt1->s[0][1]);
-                                       if( (bezt1->f1 & 1)==sel) temp+=5;
-                                       if(temp<dist) { 
-                                               hpoint=0; 
-                                               *bezt=bezt1; 
-                                               dist= temp; 
-                                               *nurb= nu; 
-                                               *bp= 0; 
-                                       }
-
-                                       /* middle points get a small disadvantage */
-                                       temp= 3+abs(mval[0]- bezt1->s[1][0])+ abs(mval[1]- bezt1->s[1][1]);
-                                       if( (bezt1->f2 & 1)==sel) temp+=5;
-                                       if(temp<dist) { 
-                                               hpoint=1; 
-                                               *bezt=bezt1; 
-                                               dist= temp; 
-                                               *nurb= nu; 
-                                               *bp= 0; 
-                                       }
-
-                                       temp= abs(mval[0]- bezt1->s[2][0])+ abs(mval[1]- bezt1->s[2][1]);
-                                       if( (bezt1->f3 & 1)==sel) temp+=5;
-                                       if(temp<dist) { 
-                                               hpoint=2; 
-                                               *bezt=bezt1; 
-                                               dist= temp; 
-                                               *nurb= nu; 
-                                               *bp= 0; 
-                                       }
-                               }
-                               bezt1++;
-                       }
-               }
-               else {
-                       bp1= nu->bp;
-                       a= nu->pntsu*nu->pntsv;
-                       while(a--) {
-                               if(bp1->hide==0) {
-                                       temp= abs(mval[0]- bp1->s[0])+ abs(mval[1]- bp1->s[1]);
-                                       if( (bp1->f1 & 1)==sel) temp+=5;
-                                       if(temp<dist) { 
-                                               hpoint=0; 
-                                               *bp=bp1; 
-                                               dist= temp; 
-                                               *nurb= nu; 
-                                               *bezt= 0; 
-                                       }
-                               }
-                               bp1++;
-                       }
+       if (bp) {
+               flag = bp->f1;
+       } else {
+               if (beztindex==0) {
+                       flag = bezt->f1;
+               } else if (beztindex==1) {
+                       flag = bezt->f2;
+               } else {
+                       flag = bezt->f3;
                }
-               nu= nu->next;
        }
 
-       return hpoint;
+       temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+       if ((flag&1)==data->select) temp += 5;
+       if (bezt && beztindex==1) temp += 3; /* middle points get a small disadvantage */
+
+       if (temp<data->dist) {
+               data->dist = temp;
+
+               data->bp = bp;
+               data->bezt = bezt;
+               data->nurb = nu;
+               data->hpoint = bezt?beztindex:0;
+       }
+}
+
+static short findnearestNurbvert(short sel, Nurb **nurb, BezTriple **bezt, BPoint **bp)
+{
+               /* sel==1: selected gets a disadvantage */
+               /* in nurb and bezt or bp the nearest is written */
+               /* return 0 1 2: handlepunt */
+       struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; short dist, hpoint, select, mval[2]; } data = {0};
+
+       data.dist = 100;
+       data.hpoint = 0;
+       data.select = sel;
+       getmouseco_areawin(data.mval);
+
+       nurbs_foreachScreenVert(findnearestNurbvert__doClosest, &data);
+
+       *nurb = data.nurb;
+       *bezt = data.bezt;
+       *bp = data.bp;
+
+       return data.hpoint;
 }
 
 
-void findselectedNurbvert(Nurb **nu, BezTriple **bezt, BPoint **bp)
+static void findselectedNurbvert(Nurb **nu, BezTriple **bezt, BPoint **bp)
 {
        /* in nu and (bezt or bp) selected are written if there's 1 sel.  */
        /* if more points selected in 1 spline: return only nu, bezt and bp are 0 */
@@ -2683,8 +2639,6 @@ void addvert_Nurb(int mode)
 
                if(bezt) {
                        nu->pntsu++;
-                       newbezt->s[1][0]= G.vd->mx;
-                       newbezt->s[1][1]= G.vd->my;
                        
                        if(mode=='e') {
                                VECCOPY(newbezt->vec[0], bezt->vec[0]);
@@ -2731,8 +2685,6 @@ void addvert_Nurb(int mode)
 
                if(bp) {
                        nu->pntsu++;
-                       newbp->s[0]= G.vd->mx;
-                       newbp->s[1]= G.vd->my;
 
                        if(nu->resolu<3) nu->resolu++;
                        makeknots(nu, 1, nu->flagu>>1);
index 89810a2a2b399d491f87f966d9dc6eaf348b4289..2f7eec5149c32a2c6be6fba77e63a5c2531b9944 100644 (file)
@@ -211,39 +211,32 @@ void deselectall_Latt(void)
        BIF_undo_push("(De)select all");
 }
 
+static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
+{
+       struct { BPoint *bp; short dist, select, mval[2]; } *data = userData;
+       short temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+       
+       if ((bp->f1&1)==data->select) temp += 5;
+       if (temp<data->dist) {
+               data->dist = temp;
 
+               data->bp = bp;
+       }
+}
 static BPoint *findnearestLattvert(int sel)
 {
-       /* sel==1: selected get a disadvantage */
-       /* in bp nearest is written */
-       BPoint *bp1, *bp;
-       short dist= 100, temp, mval[2], a;
+               /* sel==1: selected gets a disadvantage */
+               /* in nurb and bezt or bp the nearest is written */
+               /* return 0 1 2: handlepunt */
+       struct { BPoint *bp; short dist, select, mval[2]; } data = {0};
 
-       bp= 0;
+       data.dist = 100;
+       data.select = sel;
+       getmouseco_areawin(data.mval);
 
-       /* do projection */
-       calc_lattverts_ext();   /* drawobject.c */
-       
-       getmouseco_areawin(mval);
-
-                       
-       bp1= editLatt->def;
-       
-       a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
-       
-       while(a--) {
-               if(bp1->hide==0) {
-                       temp= abs(mval[0]- bp1->s[0])+ abs(mval[1]- bp1->s[1]);
-                       if( (bp1->f1 & 1)==sel) temp+=5;
-                       if(temp<dist) { 
-                               bp= bp1; 
-                               dist= temp; 
-                       }
-               }
-               bp1++;
-       }
+       lattice_foreachScreenVert(findnearestLattvert__doClosest, &data);
 
-       return bp;
+       return data.bp;
 }
 
 
index 5d1fcbf91a342420d6d3ef3b47d6af97031d3028..cd94b12feecd79ea382006dde2176180951504b8 100644 (file)
@@ -144,8 +144,6 @@ void addvert_mesh(void)
        
        curs= give_cursor();
        VECCOPY(eve->co, curs);
-       eve->xs= G.vd->mx;
-       eve->ys= G.vd->my;
        VecSubf(eve->co, eve->co, G.obedit->obmat[3]);
 
        Mat3MulVecfl(imat, eve->co);
index bc50ebdce052db992344a21dd7fd4672c77b6812..c10f7ac4c0d4092126e5cbb6a086f3541b9d2dbc 100644 (file)
@@ -636,8 +636,6 @@ void KnifeSubdivide(char mode)
        if(button(&numcuts, 2, 128, "Number of Cuts:")==0) return;
     }
 
-       calc_meshverts_ext();  /*Update screen coords for current window */
-       
        /* Set a knife cursor here */
        oldcursor=get_cursor();
 
index 08fd3981f1f5532b1d84a531d4661a6aee002c5a..89ee15af77a14f2aa7976cae47e0c50df21f0e7e 100644 (file)
@@ -194,13 +194,22 @@ static unsigned int *read_backbuf(short xmin, short ymin, short xmax, short ymax
 
 
 /* smart function to sample a rect spiralling outside, nice for backbuf selection */
-static unsigned int sample_backbuf_rect(unsigned int *buf, int size, unsigned int min, unsigned int max, short *dist)
+static unsigned int sample_backbuf_rect(short mval[2], int size, unsigned int min, unsigned int max, short *dist)
 {
-       unsigned int *bufmin, *bufmax;
+       unsigned int *buf, *bufmin, *bufmax;
+       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;
@@ -216,23 +225,26 @@ static unsigned int sample_backbuf_rect(unsigned int *buf, int size, unsigned in
                
                for(a=0; a<2; a++) {
                        for(b=0; b<nr; b++, distance++) {
-                               
-                               if(*buf && *buf>=min && *buf<max ) {
-                                       *dist= (short) sqrt( (float)distance );
-                                       return *buf - min+1;    // messy yah, but indices start at 1
+                               if (*buf && *buf>=min && *buf<max) {
+                                       *dist= (short) sqrt( (float)distance ); // XXX, this distance is wrong - zr
+                                       index = *buf - min+1; // messy yah, but indices start at 1
+                                       goto exit;
                                }
                                
                                buf+= (dirvec[rc][0]+dirvec[rc][1]);
                                
                                if(buf<bufmin || buf>=bufmax) {
-                                       return 0;
+                                       goto exit;
                                }
                        }
                        rc++;
                        rc &= 3;
                }
        }
-       return 0;
+
+exit:
+       MEM_freeN(bufmin);
+       return index;
 }
 
 /* facilities for border select and circle select */
@@ -302,14 +314,15 @@ int EM_init_backbuf_border(short xmin, short ymin, short xmax, short ymax)
        
        a= (xmax-xmin+1)*(ymax-ymin+1);
        while(a--) {
-               if(*dr>0 && *dr<=em_vertoffs) selbuf[*dr]= 1;
+               if(*dr>0 && *dr<=em_vertoffs) 
+                       selbuf[*dr]= 1;
                dr++;
        }
        MEM_freeN(buf);
        return 1;
 }
 
-int EM_check_backbuf_border(unsigned int index)
+int EM_check_backbuf(unsigned int index)
 {
        if(selbuf==NULL) return 1;
        if(index>0 && index<=em_vertoffs)
@@ -317,7 +330,7 @@ int EM_check_backbuf_border(unsigned int index)
        return 0;
 }
 
-void EM_free_backbuf_border(void)
+void EM_free_backbuf(void)
 {
        if(selbuf) MEM_freeN(selbuf);
        selbuf= NULL;
@@ -416,265 +429,241 @@ int EM_init_backbuf_circle(short xs, short ys, short rads)
        
 }
 
-
-static EditVert *findnearestvert_f(short *dist, short sel)
+static void findnearestvert__doClosest(void *userData, EditVert *eve, int x, int y, int index)
 {
-       static EditVert *acto= NULL;
-       EditMesh *em = G.editMesh;
-       /* if sel==1 the vertices with flag==1 get a disadvantage */
-       EditVert *eve,*act=NULL;
-       short temp, mval[2];
+       struct { short mval[2], pass, select, dist; int lastIndex, closestIndex; EditVert *closest; } *data = userData;
 
-       if(em->verts.first==NULL) return NULL;
-
-       /* do projection */
-       calc_meshverts_ext();   /* drawobject.c */
-       
-       /* we count from acto->next to last, and from first to acto */
-       /* does acto exist? */
-       eve= em->verts.first;
-       while(eve) {
-               if(eve==acto) break;
-               eve= eve->next;
+       if (data->pass==0) {
+               if (index<=data->lastIndex)
+                       return;
+       } else {
+               if (index>data->lastIndex)
+                       return;
        }
-       if(eve==NULL) acto= em->verts.first;
 
-       /* is there an indicated vertex? part 1 */
-       getmouseco_areawin(mval);
-       eve= acto->next;
-       while(eve) {
-               if(eve->h==0 && eve->xs!=3200) {
-                       temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
-                       if( (eve->f & 1)==sel ) temp+=5;
-                       if(temp< *dist) {
-                               act= eve;
-                               *dist= temp;
-                               if(*dist<4) break;
-                       }
-               }
-               eve= eve->next;
-       }
-       /* is there an indicated vertex? part 2 */
-       if(*dist>3) {
-               eve= em->verts.first;
-               while(eve) {
-                       if(eve->h==0 && eve->xs!=3200) {
-                               temp= abs(mval[0]- eve->xs)+ abs(mval[1]- eve->ys);
-                               if( (eve->f & 1)==sel ) temp+=5;
-                               if(temp< *dist) {
-                                       act= eve;
-                                       if(temp<4) break;
-                                       *dist= temp;
-                               }
-                               if(eve== acto) break;
-                       }
-                       eve= eve->next;
+       if (data->dist>3) {
+               short temp = abs(data->mval[0] - x) + abs(data->mval[1]- y);
+               if ((eve->f&1)==data->select) temp += 5;
+
+               if (temp<data->dist) {
+                       data->dist = temp;
+                       data->closest = eve;
+                       data->closestIndex = index;
                }
        }
-
-       acto= act;
-       return act;
 }
-
-/* backbuffer version */
 static EditVert *findnearestvert(short *dist, short sel)
 {
-       if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
-               EditVert *eve=NULL;
-               unsigned int *buf;
-               int a=1, index;
-               short mval[2], distance=255;
-               
-               getmouseco_areawin(mval);
+       short mval[2];
+
+       getmouseco_areawin(mval);
                
-               // sample colorcode 
-               buf= read_backbuf(mval[0]-25, mval[1]-25, mval[0]+24, mval[1]+24);
-               if(buf) {
-                       index= sample_backbuf_rect(buf, 50, em_wireoffs, 0xFFFFFF, &distance); // globals, set in drawobject.c
-                       MEM_freeN(buf);
-                       if(distance < *dist) {
-                               if(index>0) for(eve= G.editMesh->verts.first; eve; eve= eve->next, a++) if(index==a) break;
-                               if(eve) *dist= distance;
-                       }
+       if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
+               short distance;
+               unsigned int index = sample_backbuf_rect(mval, 50, em_wireoffs, 0xFFFFFF, &distance);
+               EditVert *eve = BLI_findlink(&G.editMesh->verts, index-1);
+
+               if (eve && distance < *dist) {
+                       *dist = distance;
+                       return eve;
+               } else {
+                       return NULL;
                }
-               return eve;
        }
-       else return findnearestvert_f(dist, sel);
-}
+       else {
+               struct { short mval[2], pass, select, dist; int lastIndex, closestIndex; EditVert *closest; } data;
+               static int lastSelectedIndex=0;
+               static EditVert *lastSelected=NULL;
 
-/* helper for findnearest edge */
-static float dist_mval_edge(short *mval, EditEdge *eed)
-{
-       float v1[2], v2[2], mval2[2];
+               if (lastSelected && BLI_findlink(&G.editMesh->verts, lastSelectedIndex)!=lastSelected) {
+                       lastSelectedIndex = 0;
+                       lastSelected = NULL;
+               }
 
-       mval2[0] = (float)mval[0];
-       mval2[1] = (float)mval[1];
-       
-       v1[0] = eed->v1->xs;
-       v1[1] = eed->v1->ys;
-       v2[0] = eed->v2->xs;
-       v2[1] = eed->v2->ys;
-       
-       return PdistVL2Dfl(mval2, v1, v2);
-}
+               data.lastIndex = lastSelectedIndex;
+               data.mval[0] = mval[0];
+               data.mval[1] = mval[1];
+               data.select = sel;
+               data.dist = *dist;
+               data.closest = NULL;
+               data.closestIndex = 0;
 
-static EditEdge *findnearestedge_f(short *dist)
-{
-       EditMesh *em = G.editMesh;
-       EditEdge *closest, *eed;
-       EditVert *eve;
-       short mval[2], distance;
-       
-       if(em->edges.first==NULL) return NULL;
-       else eed= em->edges.first;      
-       
-       calc_meshverts_ext_f2();        /* sets/clears (eve->f & 2) for vertices that aren't visible */
+               data.pass = 0;
+               mesh_foreachScreenVert(findnearestvert__doClosest, &data, 1);
 
-       getmouseco_areawin(mval);
-       closest=NULL;
-       
-       /*compare the distance to the rest of the edges and find the closest one*/
-       eed=em->edges.first;
-       while(eed) {
-               /* Are both vertices of the edge ofscreen or either of them hidden? then don't select the edge*/
-               if( !((eed->v1->f & 2) && (eed->v2->f & 2)) && eed->h==0){
-                       
-                       distance= dist_mval_edge(mval, eed);
-                       if(eed->f & SELECT) distance+=5;
-                       if(distance < *dist) {
-                               *dist= distance;
-                               closest= eed;
-                       }
+               if (data.dist>3) {
+                       data.pass = 1;
+                       mesh_foreachScreenVert(findnearestvert__doClosest, &data, 1);
                }
-               eed= eed->next;
-       }
-       
-       /* reset flags */       
-       for(eve=em->verts.first; eve; eve=eve->next){
-               eve->f &= ~2;
+
+               *dist = data.dist;
+               lastSelected = data.closest;
+               lastSelectedIndex = data.closestIndex;
+
+               return data.closest;
        }
-       
-       return closest;
 }
 
-/* backbuffer version */
-EditEdge *findnearestedge(short *dist)
+static void findnearestedge__doClosest(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index)
 {
-       if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
-               EditEdge *eed=NULL;
-               unsigned int *buf, index;
-               int a=1;
-               short mval[2], distance=255;
+       struct { float mval[2]; short dist; EditEdge *closest; } *data = userData;
+       float v1[2], v2[2];
+       short distance;
                
-               getmouseco_areawin(mval);
-               // sample colorcode 
-
-               buf= read_backbuf(mval[0]-25, mval[1]-25, mval[0]+24, mval[1]+24);
-               if(buf) {
-                       index= sample_backbuf_rect(buf, 50, em_solidoffs, em_wireoffs, &distance); // global, set in drawobject.c
-                       MEM_freeN(buf);
-                       if(distance < *dist) {
-                               if(index>0 && index<=em_wireoffs-em_solidoffs) {
-                                       for(eed= G.editMesh->edges.first; eed; eed= eed->next, a++) 
-                                               if(index==a) break;
-                               }
-                               if(eed) *dist= distance;
-                       }
-               }
+       v1[0] = x0;
+       v1[1] = y0;
+       v2[0] = x1;
+       v2[1] = y1;
+               
+       distance= PdistVL2Dfl(data->mval, v1, v2);
                
-               return eed;
+       if(eed->f & SELECT) distance+=5;
+       if(distance < data->dist) {
+               data->dist = distance;
+               data->closest = eed;
        }
-       else return findnearestedge_f(dist);
 }
+EditEdge *findnearestedge(short *dist)
+{
+       short mval[2];
+               
+       getmouseco_areawin(mval);
+
+       if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
+               short distance;
+               unsigned int index = sample_backbuf_rect(mval, 50, em_solidoffs, em_wireoffs, &distance);
+               EditEdge *eed = BLI_findlink(&G.editMesh->edges, index-1);
+
+               if (eed && distance<*dist) {
+                       *dist = distance;
+                       return eed;
+               } else {
+                       return NULL;
+               }
+       }
+       else {
+               struct { float mval[2]; short dist; EditEdge *closest; } data;
+
+               data.mval[0] = mval[0];
+               data.mval[1] = mval[1];
+               data.dist = *dist;
+               data.closest = NULL;
 
+               mesh_foreachScreenEdge(findnearestedge__doClosest, &data, 2);
+
+               *dist = data.dist;
+               return data.closest;
+       }
+}
 
-static EditFace *findnearestface_f(short *dist)
+static void findnearestface__getDistance(void *userData, EditFace *efa, int x, int y, int index)
 {
-       static EditFace *acto= NULL;
-       EditMesh *em = G.editMesh;
-       /* if selected the faces with flag==1 get a disadvantage */
-       EditFace *efa, *act=NULL;
-       short temp, mval[2];
+       struct { short mval[2], dist; EditFace *toFace; } *data = userData;
 
-       if(em->faces.first==NULL) return NULL;
+       if (efa==data->toFace) {
+               short temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
 
-       /* do projection */
-       calc_mesh_facedots_ext();
-       
-       /* we count from acto->next to last, and from first to acto */
-       /* does acto exist? */
-       efa= em->faces.first;
-       while(efa) {
-               if(efa==acto) break;
-               efa= efa->next;
+               if (temp<data->dist)
+                       data->dist = temp;
        }
-       if(efa==NULL) acto= em->faces.first;
+}
+static void findnearestface__doClosest(void *userData, EditFace *efa, int x, int y, int index)
+{
+       struct { short mval[2], pass, dist; int lastIndex, closestIndex; EditFace *closest; } *data = userData;
 
-       /* is there an indicated face? part 1 */
-       getmouseco_areawin(mval);
-       efa= acto->next;
-       while(efa) {
-               if(efa->h==0 && efa->fgonf!=EM_FGON) {
-                       temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
-                       if(temp< *dist) {
-                               act= efa;
-                               *dist= temp;
-                       }
-               }
-               efa= efa->next;
+       if (data->pass==0) {
+               if (index<=data->lastIndex)
+                       return;
+       } else {
+               if (index>data->lastIndex)
+                       return;
        }
-       /* is there an indicated face? part 2 */
-       if(*dist>3) {
-               efa= em->faces.first;
-               while(efa) {
-                       if(efa->h==0 && efa->fgonf!=EM_FGON) {
-                               temp= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
-                               if(temp< *dist) {
-                                       act= efa;
-                                       *dist= temp;
-                               }
-                               if(efa== acto) break;
-                       }
-                       efa= efa->next;
+
+       if (data->dist>3) {
+               short temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+
+               if (temp<data->dist) {
+                       data->dist = temp;
+                       data->closest = efa;
+                       data->closestIndex = index;
                }
        }
-
-       acto= act;
-       return act;
 }
-
 static EditFace *findnearestface(short *dist)
 {
+       short mval[2];
+
+       getmouseco_areawin(mval);
+
        if(G.vd->drawtype>OB_WIRE && (G.vd->flag & V3D_ZBUF_SELECT)) {
-               EditFace *efa=NULL;
-               int a=1;
-               unsigned int index;
-               short mval[2], distance;
+               unsigned int index = sample_backbuf(mval[0], mval[1]);
+               EditFace *efa = BLI_findlink(&G.editMesh->faces, index-1);
 
-               calc_mesh_facedots_ext();       // shouldnt be needed each click
-               getmouseco_areawin(mval);
+               if (efa) {
+                       struct { short mval[2], dist; EditFace *toFace; } data;
 
-               // sample colorcode 
-               index= sample_backbuf(mval[0], mval[1]);
-               
-               if(index && index<=em_solidoffs) {
-                       for(efa= G.editMesh->faces.first; efa; efa= efa->next, a++) if(index==a) break;
-                       if(efa) {
-                               distance= abs(mval[0]- efa->xs)+ abs(mval[1]- efa->ys);
-
-                               if(G.scene->selectmode == SCE_SELECT_FACE || distance<*dist) {  // only faces, no dist check
-                                       *dist= distance;
-                                       return efa;
-                               }
+                       data.mval[0] = mval[0];
+                       data.mval[1] = mval[1];
+                       data.dist = (1<<20); // just a big number
+                       data.toFace = efa;
+
+                       mesh_foreachScreenFace(findnearestface__getDistance, &data);
+
+                       if(G.scene->selectmode == SCE_SELECT_FACE || data.dist<*dist) { // only faces, no dist check
+                               *dist= data.dist;
+                               return efa;
                        }
                }
                
                return NULL;
        }
-       else return findnearestface_f(dist);
+       else {
+               struct { short mval[2], pass, dist; int lastIndex, closestIndex; EditFace *closest; } data;
+               static int lastSelectedIndex=0;
+               static EditFace *lastSelected=NULL;
+
+               if (lastSelected && BLI_findlink(&G.editMesh->faces, lastSelectedIndex)!=lastSelected) {
+                       lastSelectedIndex = 0;
+                       lastSelected = NULL;
+               }
+
+               data.lastIndex = lastSelectedIndex;
+               data.mval[0] = mval[0];
+               data.mval[1] = mval[1];
+               data.dist = *dist;
+               data.closest = NULL;
+               data.closestIndex = 0;
+
+               data.pass = 0;
+               mesh_foreachScreenFace(findnearestface__doClosest, &data);
+
+               if (data.dist>3) {
+                       data.pass = 1;
+                       mesh_foreachScreenFace(findnearestface__doClosest, &data);
+               }
+
+               *dist = data.dist;
+               lastSelected = data.closest;
+               lastSelectedIndex = data.closestIndex;
+
+               return data.closest;
+       }
 }
 
 /* for interactivity, frontbuffer draw in current window */
+static void draw_dm_mapped_vert__mapFunc(void *theVert, EditVert *eve, float *co, float *no_f, short *no_s)
+{
+       if (eve==theVert) {
+               bglVertex3fv(co);
+       }
+}
+static void draw_dm_mapped_vert(DerivedMesh *dm, EditVert *eve)
+{
+       bglBegin(GL_POINTS);
+       dm->foreachMappedVertEM(dm, draw_dm_mapped_vert__mapFunc, eve);
+       bglEnd();
+}
+
 static int draw_dm_mapped_edge__setDrawOptions(void *theEdge, EditEdge *eed)
 {
        return theEdge==eed;
@@ -684,13 +673,17 @@ static void draw_dm_mapped_edge(DerivedMesh *dm, EditEdge *eed)
        dm->drawMappedEdgesEM(dm, draw_dm_mapped_edge__setDrawOptions, eed);
 }
 
-static int draw_dm_mapped_face_center__setDrawOptions(void *theFace, EditFace *efa)
+static void draw_dm_mapped_face_center__mapFunc(void *theFace, EditFace *efa, float *cent, float *no)
 {
-       return theFace==efa;
+       if (efa==theFace) {
+               bglVertex3fv(cent);
+       }
 }
 static void draw_dm_mapped_face_center(DerivedMesh *dm, EditFace *efa)
 {
-       dm->drawMappedFaceCentersEM(dm, draw_dm_mapped_face_center__setDrawOptions, efa);
+       bglBegin(GL_POINTS);
+       dm->foreachMappedFaceCenterEM(dm, draw_dm_mapped_face_center__mapFunc, efa);
+       bglEnd();
 }
 
 static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
@@ -750,31 +743,21 @@ static void unified_select_draw(EditVert *eve, EditEdge *eed, EditFace *efa)
                        draw_dm_mapped_edge(dm, eed);
                }
                if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-                       float co[3];
                        glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
                        
                        BIF_ThemeColor((eed->f & SELECT)?TH_VERTEX_SELECT:TH_VERTEX);
                        
-                       bglBegin(GL_POINTS);
-                       dm->getMappedVertCoEM(dm, eed->v1, co);
-                       bglVertex3fv(co);
-
-                       dm->getMappedVertCoEM(dm, eed->v2, co);
-                       bglVertex3fv(co);
-                       bglEnd();
+                       draw_dm_mapped_vert(dm, eed->v1);
+                       draw_dm_mapped_vert(dm, eed->v2);
                }
        }
        if(eve) {
                if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-                       float co[3];
                        glPointSize(BIF_GetThemeValuef(TH_VERTEX_SIZE));
                        
                        BIF_ThemeColor((eve->f & SELECT)?TH_VERTEX_SELECT:TH_VERTEX);
                        
-                       bglBegin(GL_POINTS);
-                       dm->getMappedVertCoEM(dm, eve, co);
-                       bglVertex3fv(co);
-                       bglEnd();
+                       draw_dm_mapped_vert(dm, eve);
                }
        }
 
@@ -1294,7 +1277,6 @@ void hide_mesh(int swap)
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
                for(eve= em->verts.first; eve; eve= eve->next) {
                        if((eve->f & SELECT)!=swap) {
-                               eve->xs= 3200;
                                eve->f &= ~SELECT;
                                eve->h= 1;
                        }
index d4be4b6a3a5bc56ba1c908e114e300d4e445491c..78df1b9035ae88511c9e853a483bc448143e13a5 100644 (file)
@@ -103,14 +103,14 @@ static void free_tagged_facelist(EditFace *efa);
 /********* qsort routines *********/
 
 
-struct xvertsort {
+typedef struct xvertsort {
        float x;
        EditVert *v1;
-};
+} xvertsort;
 
 static int vergxco(const void *v1, const void *v2)
 {
-       const struct xvertsort *x1=v1, *x2=v2;
+       const xvertsort *x1=v1, *x2=v2;
 
        if( x1->x > x2->x ) return 1;
        else if( x1->x < x2->x) return -1;
@@ -179,7 +179,7 @@ int removedoublesflag(short flag, float limit)              /* return amount */
        EditVert *eve, *v1, *nextve;
        EditEdge *eed, *e1, *nexted;
        EditFace *efa, *nextvl;
-       struct xvertsort *sortblock, *sb, *sb1;
+       xvertsort *sortblock, *sb, *sb1;
        struct facesort *vlsortblock, *vsb, *vsb1;
        float dist;
        int a, b, test, amount;
@@ -195,7 +195,7 @@ int removedoublesflag(short flag, float limit)              /* return amount */
        if(amount==0) return 0;
 
        /* allocate memory and qsort */
-       sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*amount,"sortremovedoub");
+       sb= sortblock= MEM_mallocN(sizeof(xvertsort)*amount,"sortremovedoub");
        eve= em->verts.first;
        while(eve) {
                if(eve->h==0 && (eve->f & flag)) {
@@ -205,7 +205,7 @@ int removedoublesflag(short flag, float limit)              /* return amount */
                }
                eve= eve->next;
        }
-       qsort(sortblock, amount, sizeof(struct xvertsort), vergxco);
+       qsort(sortblock, amount, sizeof(xvertsort), vergxco);
 
        /* test for doubles */
        sb= sortblock;
@@ -427,45 +427,37 @@ int removedoublesflag(short flag, float limit)            /* return amount */
 }
 
 /* called from buttons */
+static void xsortvert_flag__doSetX(void *userData, EditVert *eve, int x, int y, int index)
+{
+       xvertsort *sortblock = userData;
+
+       sortblock[index].x = x;
+}
 void xsortvert_flag(int flag)
 {
        EditMesh *em = G.editMesh;
        /* all verts with (flag & 'flag') are sorted */
        EditVert *eve;
-       struct xvertsort *sortblock, *sb;
+       xvertsort *sortblock;
        ListBase tbase;
-       int amount;
+       int i, amount = BLI_countlist(&em->verts);
        
-       /* count */
-       eve= em->verts.first;
-       amount= 0;
-       while(eve) {
-               if(eve->f & flag) amount++;
-               eve= eve->next;
-       }
-       if(amount==0) return;
-
-       /* allocate memory and sort */
-       sb= sortblock= (struct xvertsort *)MEM_mallocN(sizeof(struct xvertsort)*amount,"sortremovedoub");
-       eve= em->verts.first;
-       while(eve) {
-               if(eve->f & flag) {
-                       sb->x= eve->xs;
-                       sb->v1= eve;
-                       sb++;
-               }
-               eve= eve->next;
-       }
-       qsort(sortblock, amount, sizeof(struct xvertsort), vergxco);
+       sortblock = MEM_callocN(sizeof(xvertsort)*amount,"xsort");
+       for (i=0,eve=em->verts.first; eve; i++,eve=eve->next)
+               if(eve->f & flag)
+                       sortblock[i].v1 = eve;
+       mesh_foreachScreenVert(xsortvert_flag__doSetX, sortblock, 0);
+       qsort(sortblock, amount, sizeof(xvertsort), vergxco);
        
-       /* make temporal listbase */
+               /* make temporal listbase */
        tbase.first= tbase.last= 0;
-       sb= sortblock;
-       while(amount--) {
-               eve= sb->v1;
-               BLI_remlink(&em->verts, eve);
-               BLI_addtail(&tbase, eve);
-               sb++;
+       for (i=0; i<amount; i++) {
+               eve = sortblock[i].v1;
+
+               if (eve) {
+                       BLI_remlink(&em->verts, eve);
+                       BLI_addtail(&tbase, eve);
+               }
        }
        
        addlisttolist(&em->verts, &tbase);
index 770d7287235e448345847cba34dfc8fb6cf276d5..041aa894dcd398d296efc2d8255b965d8d54dbce 100644 (file)
@@ -104,7 +104,48 @@ extern ListBase editNurb; /* originally from exports.h, memory from editcurve.c*
 extern ListBase editelems;
 
 /* local prototypes */
-void obedit_selectionCB(short , Object *, short *, float ); /* called in edit.c */ 
+
+void EM_backbuf_checkAndSelectVerts(EditMesh *em, int select)
+{
+       EditVert *eve;
+       int index= em_wireoffs;
+
+       for(eve= em->verts.first; eve; eve= eve->next, index++) {
+               if(eve->h==0) {
+                       if(EM_check_backbuf(index)) {
+                               eve->f = select?(eve->f|1):(eve->f&~1);
+                       }
+               }
+       }
+}
+
+void EM_backbuf_checkAndSelectEdges(EditMesh *em, int select)
+{
+       EditEdge *eed;
+       int index= em_solidoffs;
+
+       for(eed= em->edges.first; eed; eed= eed->next, index++) {
+               if(eed->h==0) {
+                       if(EM_check_backbuf(index)) {
+                               EM_select_edge(eed, select);
+                       }
+               }
+       }
+}
+
+void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select)
+{
+       EditFace *efa;
+       int index= 1;
+
+       for(efa= em->faces.first; efa; efa= efa->next, index++) {
+               if(efa->h==0) {
+                       if(EM_check_backbuf(index)) {
+                               EM_select_face_fgon(efa, select);
+                       }
+               }
+       }
+}
 
 void arrows_move_cursor(unsigned short event)
 {
@@ -126,36 +167,29 @@ void arrows_move_cursor(unsigned short event)
 /* *********************** GESTURE AND LASSO ******************* */
 
 /* helper also for borderselect */
-static int edge_fully_inside_rect(rcti rect, short x1, short y1, short x2, short y2)
+static int edge_fully_inside_rect(rcti *rect, short x1, short y1, short x2, short y2)
 {
-       
-       // check points in rect
-       if(rect.xmin<x1 && rect.xmax>x1 && rect.ymin<y1 && rect.ymax>y1) 
-               if(rect.xmin<x2 && rect.xmax>x2 && rect.ymin<y2 && rect.ymax>y2) return 1;
-       
-       return 0;
-       
+       return BLI_in_rcti(rect, x1, y1) && BLI_in_rcti(rect, x2, y2);
 }
 
-static int edge_inside_rect(rcti rect, short x1, short y1, short x2, short y2)
+static int edge_inside_rect(rcti *rect, short x1, short y1, short x2, short y2)
 {
        int d1, d2, d3, d4;
        
        // check points in rect
-       if(rect.xmin<x1 && rect.xmax>x1 && rect.ymin<y1 && rect.ymax>y1) return 1;
-       if(rect.xmin<x2 && rect.xmax>x2 && rect.ymin<y2 && rect.ymax>y2) return 1;
+       if(edge_fully_inside_rect(rect, x1, y1, x2, y2)) return 1;
        
-       /* check points completely out rect */
-       if(x1<rect.xmin && x2<rect.xmin) return 0;
-       if(x1>rect.xmax && x2>rect.xmax) return 0;
-       if(y1<rect.ymin && y2<rect.ymin) return 0;
-       if(y1>rect.ymax && y2>rect.ymax) return 0;
+       // check points completely out rect
+       if(x1<rect->xmin && x2<rect->xmin) return 0;
+       if(x1>rect->xmax && x2>rect->xmax) return 0;
+       if(y1<rect->ymin && y2<rect->ymin) return 0;
+       if(y1>rect->ymax && y2>rect->ymax) return 0;
        
        // simple check lines intersecting. 
-       d1= (y1-y2)*(x1- rect.xmin ) + (x2-x1)*(y1- rect.ymin );
-       d2= (y1-y2)*(x1- rect.xmin ) + (x2-x1)*(y1- rect.ymax );
-       d3= (y1-y2)*(x1- rect.xmax ) + (x2-x1)*(y1- rect.ymax );
-       d4= (y1-y2)*(x1- rect.xmax ) + (x2-x1)*(y1- rect.ymin );
+       d1= (y1-y2)*(x1- rect->xmin ) + (x2-x1)*(y1- rect->ymin );
+       d2= (y1-y2)*(x1- rect->xmin ) + (x2-x1)*(y1- rect->ymax );
+       d3= (y1-y2)*(x1- rect->xmax ) + (x2-x1)*(y1- rect->ymax );
+       d4= (y1-y2)*(x1- rect->xmax ) + (x2-x1)*(y1- rect->ymin );
        
        if(d1<0 && d2<0 && d3<0 && d4<0) return 0;
        if(d1>0 && d2>0 && d3>0 && d4>0) return 0;
@@ -212,10 +246,14 @@ static int lasso_inside(short mcords[][2], short moves, short sx, short sy)
 }
 
 /* edge version for lasso select. we assume boundbox check was done */
-static int lasso_inside_edge(short mcords[][2], short moves, short *v1, short *v2)
+static int lasso_inside_edge(short mcords[][2], short moves, int x0, int y0, int x1, int y1)
 {
+       short v1[2], v2[2];
        int a;
 
+       v1[0] = x0, v1[1] = y0;
+       v2[0] = x1, v2[1] = y1;
+
        // check points in lasso
        if(lasso_inside(mcords, moves, v1[0], v1[1])) return 1;
        if(lasso_inside(mcords, moves, v2[0], v2[1])) return 1;
@@ -250,7 +288,7 @@ static void do_lasso_select_pose(Object *ob, short mcords[][2], short moves, sho
                Mat4MulVecfl(ob->obmat, vec);
                project_short(vec, sco2);
                
-               if(lasso_inside_edge(mcords, moves, sco1, sco2)) {
+               if(lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) {
                        if(select) pchan->bone->flag |= BONE_SELECTED;
                        else pchan->bone->flag &= ~(BONE_ACTIVE|BONE_SELECTED);
                }
@@ -293,171 +331,138 @@ static void lasso_select_boundbox(rcti *rect, short mcords[][2], short moves)
        }
 }
 
+static void do_lasso_select_mesh__doSelectVert(void *userData, EditVert *eve, int x, int y, int index)
+{
+       struct { rcti *rect; short (*mcords)[2], moves, select, pass, done; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) {
+               eve->f = data->select?(eve->f|1):(eve->f&~1);
+       }
+}
+static void do_lasso_select_mesh__doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index)
+{
+       struct { rcti *rect; short (*mcords)[2], moves, select, pass, done; } *data = userData;
+
+       if (EM_check_backbuf(em_solidoffs+index)) {
+               if (data->pass==0) {
+                       if (    edge_fully_inside_rect(data->rect, x0, y0, x1, y1)  &&
+                                       lasso_inside(data->mcords, data->moves, x0, y0) &&
+                                       lasso_inside(data->mcords, data->moves, x1, y1)) {
+                               EM_select_edge(eed, data->select);
+                               data->done = 1;
+                       }
+               } else {
+                       if (lasso_inside_edge(data->mcords, data->moves, x0, y0, x1, y1)) {
+                               EM_select_edge(eed, data->select);
+                       }
+               }
+       }
+}
+static void do_lasso_select_mesh__doSelectFace(void *userData, EditFace *efa, int x, int y, int index)
+{
+       struct { rcti *rect; short (*mcords)[2], moves, select, pass, done; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y) && lasso_inside(data->mcords, data->moves, x, y)) {
+               EM_select_face_fgon(efa, data->select);
+       }
+}
+
 static void do_lasso_select_mesh(short mcords[][2], short moves, short select)
 {
+       struct { rcti *rect; short (*mcords)[2], moves, select, pass, done; } data;
        EditMesh *em = G.editMesh;
-       EditVert *eve;
-       EditEdge *eed;
-       EditFace *efa;
        rcti rect;
-       unsigned int index;
-       int bbsel=0; // bbsel: no clip needed with screencoords
+       int bbsel;
        
        lasso_select_boundbox(&rect, mcords, moves);
        
+       data.rect = &rect;
+       data.mcords = mcords;
+       data.moves = moves;
+       data.select = select;
+       data.done = 0;
+       data.pass = 0;
+
        bbsel= EM_mask_init_backbuf_border(mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
        
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-               if(bbsel==0) calc_meshverts_ext();      /* clips, drawobject.c */
-               index= em_wireoffs;
-               for(eve= em->verts.first; eve; eve= eve->next, index++) {
-                       if(eve->h==0) {
-                               if(bbsel) {
-                                       if(EM_check_backbuf_border(index)) {
-                                               if(select) eve->f|= 1;
-                                               else eve->f&= 254;
-                                       }
-                               }
-                               else if(eve->xs>rect.xmin && eve->xs<rect.xmax && eve->ys>rect.ymin && eve->ys<rect.ymax) {
-                                       if(lasso_inside(mcords, moves, eve->xs, eve->ys)) {
-                                               if(select) eve->f|= 1;
-                                               else eve->f&= 254;
-                                       }
-                               }
-                       }
+               if (bbsel) {
+                       EM_backbuf_checkAndSelectVerts(em, select);
+               } else {
+                       mesh_foreachScreenVert(do_lasso_select_mesh__doSelectVert, &data, 1);
                }
        }
        if(G.scene->selectmode & SCE_SELECT_EDGE) {
-               short done= 0;
-               
-               calc_meshverts_ext_f2();        /* doesnt clip, drawobject.c */
-               index= em_solidoffs;
-               
-               /* two stages, for nice edge select first do 'both points in rect' 
-                       also when bbsel is true */
-               for(eed= em->edges.first; eed; eed= eed->next, index++) {
-                       if(eed->h==0) {
-                               if(edge_fully_inside_rect(rect, eed->v1->xs, eed->v1->ys,  eed->v2->xs, eed->v2->ys)) {
-                                       if(lasso_inside(mcords, moves, eed->v1->xs, eed->v1->ys)) {
-                                               if(lasso_inside(mcords, moves, eed->v2->xs, eed->v2->ys)) {
-                                                       if(EM_check_backbuf_border(index)) {
-                                                               EM_select_edge(eed, select);
-                                                               done = 1;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-               
-               if(done==0) {
-                       index= em_solidoffs;
-                       for(eed= em->edges.first; eed; eed= eed->next, index++) {
-                               if(eed->h==0) {
-                                       if(bbsel) {
-                                               if(EM_check_backbuf_border(index))
-                                                       EM_select_edge(eed, select);
-                                       }
-                                       else if(lasso_inside_edge(mcords, moves, &eed->v1->xs, &eed->v2->xs)) {
-                                               EM_select_edge(eed, select);
-                                       }
-                               }
-                       }
+                       /* Does both bbsel and non-bbsel versions (need screen cos for both) */
+
+               data.pass = 0;
+               mesh_foreachScreenEdge(do_lasso_select_mesh__doSelectEdge, &data, 0);
+
+               if (data.done==0) {
+                       data.pass = 1;
+                       mesh_foreachScreenEdge(do_lasso_select_mesh__doSelectEdge, &data, 0);
                }
        }
        
        if(G.scene->selectmode & SCE_SELECT_FACE) {
-               if(bbsel==0) calc_mesh_facedots_ext();
-               index= 1;
-               for(efa= em->faces.first; efa; efa= efa->next, index++) {
-                       if(efa->h==0) {
-                               if(bbsel) {
-                                       if(EM_check_backbuf_border(index)) {
-                                               EM_select_face_fgon(efa, select);
-                                       }
-                               }
-                               else if(efa->xs>rect.xmin && efa->xs<rect.xmax && efa->ys>rect.ymin && efa->ys<rect.ymax) {
-                                       if(lasso_inside(mcords, moves, efa->xs, efa->ys)) {
-                                               EM_select_face_fgon(efa, select);
-                                       }
-                               }
-                       }
+               if (bbsel) {
+                       EM_backbuf_checkAndSelectFaces(em, select);
+               } else {
+                       mesh_foreachScreenFace(do_lasso_select_mesh__doSelectFace, &data);
                }
        }
        
-       EM_free_backbuf_border();
-       EM_selectmode_flush();
-       
+       EM_free_backbuf();
+       EM_selectmode_flush();  
 }
 
-static void do_lasso_select_curve(short mcords[][2], short moves, short select)
+static void do_lasso_select_curve__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
-       Nurb *nu;
-       BPoint *bp;
-       BezTriple *bezt;
-       int a;
-       
-       calc_nurbverts_ext();   /* drawobject.c */
-       nu= editNurb.first;
-       while(nu) {
-               if((nu->type & 7)==CU_BEZIER) {
-                       bezt= nu->bezt;
-                       a= nu->pntsu;
-                       while(a--) {
-                               if(bezt->hide==0) {
-                                       if(lasso_inside(mcords, moves, bezt->s[0][0], bezt->s[0][1])) {
-                                               if(select) bezt->f1|= 1;
-                                               else bezt->f1 &= ~1;
-                                       }
-                                       if(lasso_inside(mcords, moves, bezt->s[1][0], bezt->s[1][1])) {
-                                               if(select) bezt->f2|= 1;
-                                               else bezt->f2 &= ~1;
-                                       }
-                                       if(lasso_inside(mcords, moves, bezt->s[2][0], bezt->s[2][1])) {
-                                               if(select) bezt->f3|= 1;
-                                               else bezt->f3 &= ~1;
-                                       }
-                               }
-                               bezt++;
+       struct { short (*mcords)[2]; short moves; short select; } *data = userData;
+
+       if (lasso_inside(data->mcords, data->moves, x, y)) {
+               if (bp) {
+                       bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+               } else {
+                       if (beztindex==0) {
+                               bezt->f1 = data->select?(bezt->f1|1):(bezt->f1&~1);
+                       } else if (beztindex==1) {
+                               bezt->f2 = data->select?(bezt->f2|1):(bezt->f2&~1);
+                       } else {
+                               bezt->f3 = data->select?(bezt->f3|1):(bezt->f3&~1);
                        }
                }
-               else {
-                       bp= nu->bp;
-                       a= nu->pntsu*nu->pntsv;
-                       while(a--) {
-                               if(bp->hide==0) {
-                                       if(lasso_inside(mcords, moves, bp->s[0], bp->s[1])) {
-                                               if(select) bp->f1|= 1;
-                                               else bp->f1 &= ~1;
-                                       }
-                               }
-                               bp++;
-                       }
-               }
-               nu= nu->next;
        }
 }
+static void do_lasso_select_curve(short mcords[][2], short moves, short select)
+{
+       struct { short (*mcords)[2]; short moves; short select; } data;
+
+       data.mcords = mcords;
+       data.moves = moves;
+       data.select = select;
+
+       nurbs_foreachScreenVert(do_lasso_select_curve__doSelect, &data);
+}
 
-static void do_lasso_select_lattice(short mcords[][2], short moves, short select)
+static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y)
 {
-       BPoint *bp;
-       int a;
-       
-       calc_lattverts_ext();
-       
-       bp= editLatt->def;
-       
-       a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
-       while(a--) {
-               if(bp->hide==0) {
-                       if(lasso_inside(mcords, moves, bp->s[0], bp->s[1])) {
-                               if(select) bp->f1|= 1;
-                               else bp->f1 &= ~1;
-                       }
-               }
-               bp++;
+       struct { short (*mcords)[2]; short moves; short select; } *data = userData;
+
+       if (lasso_inside(data->mcords, data->moves, x, y)) {
+               bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
        }
 }
+static void do_lasso_select_lattice(short mcords[][2], short moves, short select)
+{
+       struct { short (*mcords)[2]; short moves; short select; } data;
+
+       data.mcords = mcords;
+       data.moves = moves;
+       data.select = select;
+
+       lattice_foreachScreenVert(do_lasso_select_lattice__doSelect, &data);
+}
 
 static void do_lasso_select_armature(short mcords[][2], short moves, short select)
 {
@@ -486,7 +491,7 @@ static void do_lasso_select_armature(short mcords[][2], short moves, short selec
                   didpoint= 1;
                }
                /* if one of points selected, we skip the bone itself */
-               if(didpoint==0 && lasso_inside_edge(mcords, moves, sco1, sco2)) {
+               if(didpoint==0 && lasso_inside_edge(mcords, moves, sco1[0], sco1[1], sco2[0], sco2[1])) {
                        if(select) ebone->flag |= BONE_TIPSEL|BONE_ROOTSEL|BONE_SELECTED;
                        else ebone->flag &= ~(BONE_ACTIVE|BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL);
                }
@@ -512,13 +517,12 @@ static void do_lasso_select_facemode(short mcords[][2], short moves, short selec
        EM_mask_init_backbuf_border(mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
        
        for(a=1; a<=me->totface; a++, tface++) {
-               if(EM_check_backbuf_border(a)) {
-                       if(select) tface->flag |= TF_SELECT;
-                       else tface->flag &= ~TF_SELECT;
+               if(EM_check_backbuf(a)) {
+                       tface->flag = select?(tface->flag|TF_SELECT):(tface->flag&~TF_SELECT);
                }
        }
        
-       EM_free_backbuf_border();
+       EM_free_backbuf();
        
        allqueue(REDRAWVIEW3D, 0);
        allqueue(REDRAWIMAGE, 0);
@@ -1370,6 +1374,129 @@ static int edge_inside_circle(short centx, short centy, short rad, short x1, sho
        return 0;
 }
 
+static void do_nurbs_box_select__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
+{
+       struct { rcti *rect; int select; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y)) {
+               if (bp) {
+                       bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+               } else {
+                       if (beztindex==0) {
+                               bezt->f1 = data->select?(bezt->f1|1):(bezt->f1&~1);
+                       } else if (beztindex==1) {
+                               bezt->f2 = data->select?(bezt->f2|1):(bezt->f2&~1);
+                       } else {
+                               bezt->f3 = data->select?(bezt->f3|1):(bezt->f3&~1);
+                       }
+               }
+       }
+}
+static void do_nurbs_box_select(rcti *rect, int select)
+{
+       struct { rcti *rect; int select; } data;
+
+       data.rect = rect;
+       data.select = select;
+
+       nurbs_foreachScreenVert(do_nurbs_box_select__doSelect, &data);
+}
+
+static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y)
+{
+       struct { rcti *rect; int select; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y)) {
+               bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+       }
+}
+static void do_lattice_box_select(rcti *rect, int select)
+{
+       struct { rcti *rect; short select, pass, done; } data;
+
+       data.rect = rect;
+       data.select = select;
+
+       lattice_foreachScreenVert(do_lattice_box_select__doSelect, &data);
+}
+
+static void do_mesh_box_select__doSelectVert(void *userData, EditVert *eve, int x, int y, int index)
+{
+       struct { rcti *rect; short select, pass, done; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y)) {
+               eve->f = data->select?(eve->f|1):(eve->f&~1);
+       }
+}
+static void do_mesh_box_select__doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index)
+{
+       struct { rcti *rect; short select, pass, done; } *data = userData;
+
+       if(EM_check_backbuf(em_solidoffs+index)) {
+               if (data->pass==0) {
+                       if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) {
+                               EM_select_edge(eed, data->select);
+                               data->done = 1;
+                       }
+               } else {
+                       if (edge_inside_rect(data->rect, x0, y0, x1, y1)) {
+                               EM_select_edge(eed, data->select);
+                       }
+               }
+       }
+}
+static void do_mesh_box_select__doSelectFace(void *userData, EditFace *efa, int x, int y, int index)
+{
+       struct { rcti *rect; short select, pass, done; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y)) {
+               EM_select_face_fgon(efa, data->select);
+       }
+}
+static void do_mesh_box_select(rcti *rect, int select)
+{
+       struct { rcti *rect; short select, pass, done; } data;
+       EditMesh *em = G.editMesh;
+       int bbsel;
+       
+       data.rect = rect;
+       data.select = select;
+       data.pass = 0;
+       data.done = 0;
+
+       bbsel= EM_init_backbuf_border(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+       if(G.scene->selectmode & SCE_SELECT_VERTEX) {
+               if (bbsel) {
+                       EM_backbuf_checkAndSelectVerts(em, select);
+               } else {
+                       mesh_foreachScreenVert(do_mesh_box_select__doSelectVert, &data, 1);
+               }
+       }
+       if(G.scene->selectmode & SCE_SELECT_EDGE) {
+                       /* Does both bbsel and non-bbsel versions (need screen cos for both) */
+
+               data.pass = 0;
+               mesh_foreachScreenEdge(do_mesh_box_select__doSelectEdge, &data, 0);
+
+               if (data.done==0) {
+                       data.pass = 1;
+                       mesh_foreachScreenEdge(do_mesh_box_select__doSelectEdge, &data, 0);
+               }
+       }
+       
+       if(G.scene->selectmode & SCE_SELECT_FACE) {
+               if(bbsel) {
+                       EM_backbuf_checkAndSelectFaces(em, select);
+               } else {
+                       mesh_foreachScreenFace(do_mesh_box_select__doSelectFace, &data);
+               }
+       }
+       
+       EM_free_backbuf();
+               
+       EM_selectmode_flush();
+}
 
 /**
  * Does the 'borderselect' command. (Select verts based on selecting with a 
@@ -1379,9 +1506,6 @@ void borderselect(void)
 {
        rcti rect;
        Base *base;
-       Nurb *nu;
-       BezTriple *bezt;
-       BPoint *bp;
        MetaElem *ml;
        unsigned int buffer[MAXPICKBUF];
        int a, index;
@@ -1401,135 +1525,11 @@ void borderselect(void)
        
        if(G.obedit) {
                if(G.obedit->type==OB_MESH) {
-                       EditMesh *em = G.editMesh;
-                       EditVert *eve;
-                       EditEdge *eed;
-                       EditFace *efa;
-                       int index, bbsel=0; // bbsel: no clip needed with screencoords
-                       
-                       bbsel= EM_init_backbuf_border(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
-
-                       if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-                               if(bbsel==0) calc_meshverts_ext();      /* clips, drawobject.c */
-                               index= em_wireoffs;
-                               for(eve= em->verts.first; eve; eve= eve->next, index++) {
-                                       if(eve->h==0) {
-                                               if(bbsel || (eve->xs>rect.xmin && eve->xs<rect.xmax && eve->ys>rect.ymin && eve->ys<rect.ymax)) {
-                                                       if(EM_check_backbuf_border(index)) {
-                                                               if(val==LEFTMOUSE) eve->f|= 1;
-                                                               else eve->f&= 254;
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       if(G.scene->selectmode & SCE_SELECT_EDGE) {
-                               short done= 0;
-                               
-                               calc_meshverts_ext_f2();        /* doesnt clip, drawobject.c */
-                               index= em_solidoffs;
-                               /* two stages, for nice edge select first do 'both points in rect'
-                                  also when bbsel is true */
-                               for(eed= em->edges.first; eed; eed= eed->next, index++) {
-                                       if(eed->h==0) {
-                                               if(edge_fully_inside_rect(rect, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) {
-                                                       if(EM_check_backbuf_border(index)) {
-                                                               EM_select_edge(eed, val==LEFTMOUSE);
-                                                               done = 1;
-                                                       }
-                                               }
-                                       }
-                               }
-
-                               if(done==0) {
-                                       index= em_solidoffs;
-                                       for(eed= em->edges.first; eed; eed= eed->next, index++) {
-                                               if(eed->h==0) {
-                                                       if(bbsel) {
-                                                               if(EM_check_backbuf_border(index))
-                                                                       EM_select_edge(eed, val==LEFTMOUSE);
-                                                       }
-                                                       else if(edge_inside_rect(rect, eed->v1->xs, eed->v1->ys, eed->v2->xs, eed->v2->ys)) {
-                                                               EM_select_edge(eed, val==LEFTMOUSE);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       if(G.scene->selectmode & SCE_SELECT_FACE) {
-                               if(bbsel==0) calc_mesh_facedots_ext();
-                               index= 1;
-                               for(efa= em->faces.first; efa; efa= efa->next, index++) {
-                                       if(efa->h==0) {
-                                               if(bbsel || (efa->xs>rect.xmin && efa->xs<rect.xmax && efa->ys>rect.ymin && efa->ys<rect.ymax)) {
-                                                       if(EM_check_backbuf_border(index)) {
-                                                               EM_select_face_fgon(efa, val==LEFTMOUSE);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-                       
-                       EM_free_backbuf_border();
-                               
-                       EM_selectmode_flush();
+                       do_mesh_box_select(&rect, (val==LEFTMOUSE));
                        allqueue(REDRAWVIEW3D, 0);
-                       
                }
                else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
-                       
-                       calc_nurbverts_ext();   /* drawobject.c */
-                       nu= editNurb.first;
-                       while(nu) {
-                               if((nu->type & 7)==CU_BEZIER) {
-                                       bezt= nu->bezt;
-                                       a= nu->pntsu;
-                                       while(a--) {
-                                               if(bezt->hide==0) {
-                                                       if(bezt->s[0][0]>rect.xmin && bezt->s[0][0]<rect.xmax) {
-                                                               if(bezt->s[0][1]>rect.ymin && bezt->s[0][1]<rect.ymax) {
-                                                                       if(val==LEFTMOUSE) bezt->f1|= 1;
-                                                                       else bezt->f1 &= ~1;
-                                                               }
-                                                       }
-                                                       if(bezt->s[1][0]>rect.xmin && bezt->s[1][0]<rect.xmax) {
-                                                               if(bezt->s[1][1]>rect.ymin && bezt->s[1][1]<rect.ymax) {
-                                                                       if(val==LEFTMOUSE) {
-                                                                               bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1;
-                                                                       }
-                                                                       else {
-                                                                               bezt->f1 &= ~1; bezt->f2 &= ~1; bezt->f3 &= ~1;
-                                                                       }
-                                                               }
-                                                       }
-                                                       if(bezt->s[2][0]>rect.xmin && bezt->s[2][0]<rect.xmax) {
-                                                               if(bezt->s[2][1]>rect.ymin && bezt->s[2][1]<rect.ymax) {
-                                                                       if(val==LEFTMOUSE) bezt->f3|= 1;
-                                                                       else bezt->f3 &= ~1;
-                                                               }
-                                                       }
-                                               }
-                                               bezt++;
-                                       }
-                               }
-                               else {
-                                       bp= nu->bp;
-                                       a= nu->pntsu*nu->pntsv;
-                                       while(a--) {
-                                               if(bp->hide==0) {
-                                                       if(bp->s[0]>rect.xmin && bp->s[0]<rect.xmax) {
-                                                               if(bp->s[1]>rect.ymin && bp->s[1]<rect.ymax) {
-                                                                       if(val==LEFTMOUSE) bp->f1|= 1;
-                                                                       else bp->f1 &= ~1;
-                                                               }
-                                                       }
-                                               }
-                                               bp++;
-                                       }
-                               }
-                               nu= nu->next;
-                       }
+                       do_nurbs_box_select(&rect, val==LEFTMOUSE);
                        allqueue(REDRAWVIEW3D, 0);
                }
                else if(G.obedit->type==OB_MBALL) {
@@ -1590,23 +1590,7 @@ void borderselect(void)
                        allqueue(REDRAWVIEW3D, 0);
                }
                else if(G.obedit->type==OB_LATTICE) {
-                       
-                       calc_lattverts_ext();
-                       
-                       bp= editLatt->def;
-
-                       a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
-                       while(a--) {
-                               if(bp->hide==0) {
-                                       if(bp->s[0]>rect.xmin && bp->s[0]<rect.xmax) {
-                                               if(bp->s[1]>rect.ymin && bp->s[1]<rect.ymax) {
-                                                       if(val==LEFTMOUSE) bp->f1|= 1;
-                                                       else bp->f1 &= ~1;
-                                               }
-                                       }
-                               }
-                               bp++;
-                       }
+                       do_lattice_box_select(&rect, val==LEFTMOUSE);
                        allqueue(REDRAWVIEW3D, 0);
                }
        }
@@ -1704,177 +1688,129 @@ void borderselect(void)
        XXX These callback functions are still dirty, because they call globals... 
   */
 
+static void mesh_selectionCB__doSelectVert(void *userData, EditVert *eve, int x, int y, int index)
+{
+       struct { short select, mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+
+       if (r<=data->radius) {
+               eve->f = data->select?(eve->f|1):(eve->f&~1);
+       }
+}
+static void mesh_selectionCB__doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index)
+{
+       struct { short select, mval[2]; float radius; } *data = userData;
+
+       if (edge_inside_circle(data->mval[0], data->mval[1], (short) data->radius, x0, y0, x1, y1)) {
+               EM_select_edge(eed, data->select);
+       }
+}
+static void mesh_selectionCB__doSelectFace(void *userData, EditFace *efa, int x, int y, int index)
+{
+       struct { short select, mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+
+       if (r<=data->radius) {
+               EM_select_face_fgon(efa, data->select);
+       }
+}
 static void mesh_selectionCB(int selecting, Object *editobj, short *mval, float rad)
 {
+       struct { short select, mval[2]; float radius; } data;
        EditMesh *em = G.editMesh;
-       EditVert *eve;
-       EditEdge *eed;
-       EditFace *efa;
-       float x, y, r;
-       int index, bbsel=0; // if bbsel we dont clip with screencoords
-       short rads= (short)(rad+1.0);
+       int bbsel;
        
-       bbsel= EM_init_backbuf_circle(mval[0], mval[1], rads);
+       bbsel= EM_init_backbuf_circle(mval[0], mval[1], (short)(rad+1.0));
        
+       data.select = (selecting==LEFTMOUSE);
+       data.mval[0] = mval[0];
+       data.mval[1] = mval[1];
+       data.radius = rad;
+
        if(G.scene->selectmode & SCE_SELECT_VERTEX) {
-               if(bbsel==0) calc_meshverts_ext();      /* drawobject.c */
-               index= em_wireoffs;
-               for(eve= em->verts.first; eve; eve= eve->next, index++) {
-                       if(eve->h==0) {
-                               if(bbsel) {
-                                       if(EM_check_backbuf_border(index)) {
-                                               if(selecting==LEFTMOUSE) eve->f|= 1;
-                                               else eve->f&= 254;
-                                       }
-                               }
-                               else {
-                                       x= eve->xs-mval[0];
-                                       y= eve->ys-mval[1];
-                                       r= sqrt(x*x+y*y);
-                                       if(r<=rad) {
-                                               if(selecting==LEFTMOUSE) eve->f|= 1;
-                                               else eve->f&= 254;
-                                       }
-                               }
-                       }
+               if(bbsel) {
+                       EM_backbuf_checkAndSelectVerts(em, selecting==LEFTMOUSE);
+               } else {
+                       mesh_foreachScreenVert(mesh_selectionCB__doSelectVert, &data, 1);
                }
        }
 
        if(G.scene->selectmode & SCE_SELECT_EDGE) {
-               if(bbsel==0) calc_meshverts_ext_f2();   /* doesnt clip, drawobject.c */
-               index= em_solidoffs;
-               for(eed= em->edges.first; eed; eed= eed->next, index++) {
-                       if(eed->h==0) {
-                               if(bbsel || edge_inside_circle(mval[0], mval[1], (short)rad, eed->v1->xs, eed->v1->ys,  eed->v2->xs, eed->v2->ys)) {
-                                       if(EM_check_backbuf_border(index)) {
-                                               EM_select_edge(eed, selecting==LEFTMOUSE);
-                                       }
-                               }
-                       }
+               if (bbsel) {
+                       EM_backbuf_checkAndSelectEdges(em, selecting==LEFTMOUSE);
+               } else {
+                       mesh_foreachScreenEdge(mesh_selectionCB__doSelectEdge, &data, 0);
                }
        }
        
        if(G.scene->selectmode & SCE_SELECT_FACE) {
-               if(bbsel==0) calc_mesh_facedots_ext();
-               index= 1;
-               for(efa= em->faces.first; efa; efa= efa->next, index++) {
-                       if(efa->h==0) {
-                               if(bbsel) {
-                                       if(EM_check_backbuf_border(index)) {
-                                               EM_select_face_fgon(efa, selecting==LEFTMOUSE);
-                                       }
-                               }
-                               else {
-                                       x= efa->xs-mval[0];
-                                       y= efa->ys-mval[1];
-                                       r= sqrt(x*x+y*y);
-                                       if(r<=rad) {
-                                               EM_select_face_fgon(efa, selecting==LEFTMOUSE);
-                                       }
-                               }
-                       }
+               if(bbsel) {
+                       EM_backbuf_checkAndSelectFaces(em, selecting==LEFTMOUSE);
+               } else {
+                       mesh_foreachScreenFace(mesh_selectionCB__doSelectFace, &data);
                }
        }
-       EM_free_backbuf_border();
-       EM_selectmode_flush();
-
-       draw_sel_circle(0, 0, 0, 0, 0); /* signal */
-       force_draw(0);
 
+       EM_free_backbuf();
+       EM_selectmode_flush();
 }
 
 
-static void nurbscurve_selectionCB(int selecting, Object *editobj, short *mval, float rad)
+static void nurbscurve_selectionCB__doSelect(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
-       Nurb *nu;
-       BPoint *bp;
-       BezTriple *bezt;
-       float x, y, r;
-       int a;
-
-       calc_nurbverts_ext();   /* drawobject.c */
-       nu= editNurb.first;
-       while(nu) {
-               if((nu->type & 7)==CU_BEZIER) {
-                       bezt= nu->bezt;
-                       a= nu->pntsu;
-                       while(a--) {
-                               if(bezt->hide==0) {
-                                       x= bezt->s[0][0]-mval[0];
-                                       y= bezt->s[0][1]-mval[1];
-                                       r= sqrt(x*x+y*y);
-                                       if(r<=rad) {
-                                               if(selecting==LEFTMOUSE) bezt->f1|= 1;
-                                               else bezt->f1 &= ~1;
-                                       }
-                                       x= bezt->s[1][0]-mval[0];
-                                       y= bezt->s[1][1]-mval[1];
-                                       r= sqrt(x*x+y*y);
-                                       if(r<=rad) {
-                                               if(selecting==LEFTMOUSE) bezt->f2|= 1;
-                                               else bezt->f2 &= ~1;
-                                       }
-                                       x= bezt->s[2][0]-mval[0];
-                                       y= bezt->s[2][1]-mval[1];
-                                       r= sqrt(x*x+y*y);
-                                       if(r<=rad) {
-                                               if(selecting==LEFTMOUSE) bezt->f3|= 1;
-                                               else bezt->f3 &= ~1;
-                                       }
-                                       
-                               }
-                               bezt++;
-                       }
-               }
-               else {
-                       bp= nu->bp;
-                       a= nu->pntsu*nu->pntsv;
-                       while(a--) {
-                               if(bp->hide==0) {
-                                       x= bp->s[0]-mval[0];
-                                       y= bp->s[1]-mval[1];
-                                       r= sqrt(x*x+y*y);
-                                       if(r<=rad) {
-                                               if(selecting==LEFTMOUSE) bp->f1|= 1;
-                                               else bp->f1 &= ~1;
-                                       }
-                               }
-                               bp++;
+       struct { short select, mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+
+       if (r<=data->radius) {
+               if (bp) {
+                       bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+               } else {
+                       if (beztindex==0) {
+                               bezt->f1 = data->select?(bezt->f1|1):(bezt->f1&~1);
+                       } else if (beztindex==1) {
+                               bezt->f2 = data->select?(bezt->f2|1):(bezt->f2&~1);
+                       } else {
+                               bezt->f3 = data->select?(bezt->f3|1):(bezt->f3&~1);
                        }
                }
-               nu= nu->next;
        }
-       draw_sel_circle(0, 0, 0, 0, 0); /* signal */
-       force_draw(0);
+}
+static void nurbscurve_selectionCB(int selecting, Object *editobj, short *mval, float rad)
+{
+       struct { short select, mval[2]; float radius; } data;
 
+       data.select = (selecting==LEFTMOUSE);
+       data.mval[0] = mval[0];
+       data.mval[1] = mval[1];
+       data.radius = rad;
 
+       nurbs_foreachScreenVert(nurbscurve_selectionCB__doSelect, &data);
 }
 
+
+static void latticecurve_selectionCB__doSelect(void *userData, BPoint *bp, int x, int y)
+{
+       struct { short select, mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+
+       if (r<=data->radius) {
+               bp->f1 = data->select?(bp->f1|1):(bp->f1&~1);
+       }
+}
 static void lattice_selectionCB(int selecting, Object *editobj, short *mval, float rad)
 {
-       BPoint *bp;
-       float x, y, r;
-       int a;
+       struct { short select, mval[2]; float radius; } data;
 
-       calc_lattverts_ext();
-       
-       bp= editLatt->def;
+       data.select = (selecting==LEFTMOUSE);
+       data.mval[0] = mval[0];
+       data.mval[1] = mval[1];
+       data.radius = rad;
 
-       a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
-       while(a--) {
-               if(bp->hide==0) {
-                       x= bp->s[0]-mval[0];
-                       y= bp->s[1]-mval[1];
-                       r= sqrt(x*x+y*y);
-                       if(r<=rad) {
-                               if(selecting==LEFTMOUSE) bp->f1|= 1;
-                               else bp->f1 &= ~1;
-                       }
-               }
-               bp++;
-       }
-       draw_sel_circle(0, 0, 0, 0, 0); /* signal */
-       force_draw(0);
+       lattice_foreachScreenVert(latticecurve_selectionCB__doSelect, &data);
 }
 
 /** Callbacks for selection in Editmode */
@@ -1892,7 +1828,12 @@ void obedit_selectionCB(short selecting, Object *editobj, short *mval, float rad
        case OB_LATTICE:
                lattice_selectionCB(selecting, editobj, mval, rad);
                break;
+       default:
+               return;
        }
+
+       draw_sel_circle(0, 0, 0, 0, 0); /* signal */
+       force_draw(0);
 }
 
 void set_render_border(void)
index 55dd981c5764e095430ce492ad2e3bc30fb63e3d..c71abf151344831ef8cb25de00ca01d2796df6f1 100644 (file)
@@ -60,7 +60,6 @@
 #include "DNA_view3d_types.h"
 
 #include "BKE_armature.h"
-#include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BKE_lattice.h"
 #include "BKE_object.h"
@@ -175,8 +174,6 @@ int calc_manipulator_stats(ScrArea *sa)
                if((ob->lay & G.vd->lay)==0) return 0;
 
                if(G.obedit->type==OB_MESH) {
-                       int dmNeedsFree;
-                       DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
                        EditMesh *em = G.editMesh;
                        EditVert *eve;
                        float vec[3];
@@ -201,8 +198,7 @@ int calc_manipulator_stats(ScrArea *sa)
                                        if(no_faces) VECADD(normal, normal, eve->no);
                                        
                                        totsel++;
-                                       dm->getMappedVertCoEM(dm, eve, vec);
-                                       calc_tw_center(vec);
+                                       calc_tw_center(eve->co);
                                }
                        }
                        /* the edge case... */
@@ -218,9 +214,6 @@ int calc_manipulator_stats(ScrArea *sa)
                                        }
                                }
                        }
-                       if (dmNeedsFree) {
-                               dm->release(dm);
-                       }
                }
                else if (G.obedit->type==OB_ARMATURE){
                        EditBone *ebo;