Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2004-09-24 16:40:37 +0400
committerTon Roosendaal <ton@blender.org>2004-09-24 16:40:37 +0400
commitf59503682d1afdb29079dccd642b4191ff9ecc1e (patch)
treefed8a2a9682a6a1892d03528d9bd2b7b27c20e36 /source
parentce12a0173c25fdb9cbe34aee194bdf62780230bc (diff)
- basic code for fake-polygon support (called FGon in code). Disabled now
- hide flags now save correctly in mesh, to restore after going in/out editmode - after an extrude, faces/edges could have wrong select flags (only in vertex select mode) - new rule for addfacelist(); this now copies edges too, if an example is provided. That prevents a lot of awkward code, still testing if it goes as desired though...
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenlib/BLI_editVert.h6
-rw-r--r--source/blender/include/BIF_editmesh.h6
-rw-r--r--source/blender/include/editmesh.h2
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h2
-rw-r--r--source/blender/src/drawobject.c53
-rw-r--r--source/blender/src/editmesh.c47
-rw-r--r--source/blender/src/editmesh_add.c6
-rw-r--r--source/blender/src/editmesh_lib.c2
-rw-r--r--source/blender/src/editmesh_mods.c242
-rw-r--r--source/blender/src/space.c6
10 files changed, 322 insertions, 50 deletions
diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h
index 0ff57f8cde7..e47d82043b7 100644
--- a/source/blender/blenlib/BLI_editVert.h
+++ b/source/blender/blenlib/BLI_editVert.h
@@ -66,7 +66,8 @@ typedef struct EditEdge
short f1, f2; /* short, f1 is (ab)used in subdiv */
unsigned char f, h, dir, seam;
float crease;
- int fast; /* only 0 or 1, for editmesh_fastmalloc */
+ short fast; /* only 0 or 1, for editmesh_fastmalloc */
+ short fgoni; /* index for fgon, for search */
HashEdge hash;
} EditEdge;
@@ -80,7 +81,8 @@ typedef struct EditFace
struct TFace tf; /* a copy of original tface. */
unsigned char mat_nr, flag;
unsigned char f, f1, h, puno;
- short fast; /* only 0 or 1, for editmesh_fastmalloc */
+ unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */
+ unsigned char fgonf; /* flag for fgon options */
} EditFace;
typedef struct EditMesh
diff --git a/source/blender/include/BIF_editmesh.h b/source/blender/include/BIF_editmesh.h
index fe11e0b684e..632283f9a53 100644
--- a/source/blender/include/BIF_editmesh.h
+++ b/source/blender/include/BIF_editmesh.h
@@ -43,6 +43,12 @@ struct Mesh;
struct bDeformGroup;
struct View3D;
+// edge and face flag both
+#define EM_FGON 2
+// face flag
+#define EM_FGON_DRAW 1
+
+
/* ******************* editmesh.c */
extern void make_editMesh(void);
extern void load_editMesh(void);
diff --git a/source/blender/include/editmesh.h b/source/blender/include/editmesh.h
index bb69b033cb7..927c8d40156 100644
--- a/source/blender/include/editmesh.h
+++ b/source/blender/include/editmesh.h
@@ -41,6 +41,7 @@
#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float));
+
/* ******************* editmesh.c */
extern void free_editvert(EditVert *eve);
extern void free_editedge(EditEdge *eed);
@@ -82,6 +83,7 @@ extern float convex(float *v1, float *v2, float *v3, float *v4);
/* ******************* editmesh_mods.c */
extern EditEdge *findnearestedge(short *dist);
+extern void make_fgon(void);
/* ******************* editmesh_tools.c */
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 426c06366ca..0a186765cae 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -80,6 +80,8 @@ typedef struct MSticky {
/* medge->flag (1=SELECT)*/
#define ME_EDGEDRAW 2
#define ME_SEAM 4
+#define ME_FGON 8
+ // reserve 16 for ME_HIDE
/* puno = vertexnormal (mface) */
#define ME_FLIPV1 1
diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c
index bba7864a6cd..ddfef9c6cb0 100644
--- a/source/blender/src/drawobject.c
+++ b/source/blender/src/drawobject.c
@@ -1153,7 +1153,8 @@ static void draw_vertices(short sel)
bglBegin(GL_POINTS);
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->h==0) {
- if(sel == (efa->f & SELECT)) {
+ if(efa->fgonf==EM_FGON);
+ else if(sel == (efa->f & SELECT)) {
bglVertex3fv(efa->cent);
}
}
@@ -1183,7 +1184,8 @@ static void draw_vertices(short sel)
bglBegin(GL_POINTS);
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->h==0) {
- if(sel == (efa->f & SELECT)) {
+ if(efa->fgonf==EM_FGON);
+ else if(sel == (efa->f & SELECT)) {
bglVertex3fv(efa->cent);
}
}
@@ -2521,27 +2523,50 @@ static void drawmeshwire(Object *ob)
else if(G.scene->selectmode == SCE_SELECT_FACE) {
/* draw faces twice, to have selected ones on top */
BIF_ThemeColor(TH_WIRE);
+ glBegin(GL_LINES);
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->h==0 && (efa->f & SELECT)==0) {
- glBegin(GL_LINE_LOOP);
- glVertex3fv(efa->v1->co);
- glVertex3fv(efa->v2->co);
- glVertex3fv(efa->v3->co);
- if(efa->v4) glVertex3fv(efa->v4->co);
- glEnd();
+ if(efa->e1->h==0) {
+ glVertex3fv(efa->v1->co);
+ glVertex3fv(efa->v2->co);
+ }
+ if(efa->e2->h==0) {
+ glVertex3fv(efa->v2->co);
+ glVertex3fv(efa->v3->co);
+ }
+ if(efa->e3->h==0) {
+ glVertex3fv(efa->e3->v1->co);
+ glVertex3fv(efa->e3->v2->co);
+ }
+ if(efa->e4 && efa->e4->h==0) {
+ glVertex3fv(efa->e4->v1->co);
+ glVertex3fv(efa->e4->v2->co);
+ }
}
}
+
BIF_ThemeColor(TH_EDGE_SELECT);
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->h==0 && (efa->f & SELECT)) {
- glBegin(GL_LINE_LOOP);
- glVertex3fv(efa->v1->co);
- glVertex3fv(efa->v2->co);
- glVertex3fv(efa->v3->co);
- if(efa->v4) glVertex3fv(efa->v4->co);
- glEnd();
+ if(efa->e1->h==0) {
+ glVertex3fv(efa->v1->co);
+ glVertex3fv(efa->v2->co);
+ }
+ if(efa->e2->h==0) {
+ glVertex3fv(efa->v2->co);
+ glVertex3fv(efa->v3->co);
+ }
+ if(efa->e3->h==0) {
+ glVertex3fv(efa->e3->v1->co);
+ glVertex3fv(efa->e3->v2->co);
+ }
+ if(efa->e4 && efa->e4->h==0) {
+ glVertex3fv(efa->e4->v1->co);
+ glVertex3fv(efa->e4->v2->co);
+ }
}
}
+ glEnd();
}
else if( (G.f & G_DRAWEDGES) || (G.scene->selectmode & SCE_SELECT_EDGE) ) {
/* Use edge highlighting */
diff --git a/source/blender/src/editmesh.c b/source/blender/src/editmesh.c
index 18f815ff15e..cc1f675a4bd 100644
--- a/source/blender/src/editmesh.c
+++ b/source/blender/src/editmesh.c
@@ -246,18 +246,20 @@ EditEdge *addedgelist(EditVert *v1, EditVert *v2, EditEdge *example)
eed= findedgelist(v1, v2);
if(eed==NULL) {
-
+
eed= (EditEdge *)callocedge(sizeof(EditEdge), 1);
eed->v1= v1;
eed->v2= v2;
BLI_addtail(&em->edges, eed);
eed->dir= swap;
insert_hashedge(eed);
+
/* copy edge data:
rule is to do this with addedgelist call, before addfacelist */
if(example) {
eed->crease= example->crease;
eed->seam = example->seam;
+ eed->h |= (example->h & EM_FGON);
}
}
@@ -330,12 +332,21 @@ EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, Ed
EditEdge *e1, *e2=0, *e3=0, *e4=0;
/* add face to list and do the edges */
- e1= addedgelist(v1, v2, NULL);
- e2= addedgelist(v2, v3, NULL);
- if(v4) e3= addedgelist(v3, v4, NULL);
- else e3= addedgelist(v3, v1, NULL);
- if(v4) e4= addedgelist(v4, v1, NULL);
-
+ if(example) {
+ e1= addedgelist(v1, v2, example->e1);
+ e2= addedgelist(v2, v3, example->e2);
+ if(v4) e3= addedgelist(v3, v4, example->e3);
+ else e3= addedgelist(v3, v1, example->e3);
+ if(v4) e4= addedgelist(v4, v1, example->e4);
+ }
+ else {
+ e1= addedgelist(v1, v2, NULL);
+ e2= addedgelist(v2, v3, NULL);
+ if(v4) e3= addedgelist(v3, v4, NULL);
+ else e3= addedgelist(v3, v1, NULL);
+ if(v4) e4= addedgelist(v4, v1, NULL);
+ }
+
if(v1==v2 || v2==v3 || v1==v3) return NULL;
if(e2==0) return NULL;
@@ -704,6 +715,8 @@ void make_editMesh()
if(medge->flag & ME_SEAM) eed->seam= 1;
if(medge->flag & SELECT) eed->f |= SELECT;
+ if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines!
+ if(medge->flag & ME_HIDE) eed->h |= 1;
}
}
@@ -743,6 +756,7 @@ void make_editMesh()
efa->f |= SELECT;
if(me->medge==NULL) EM_select_face(efa, 1);
}
+ if(mface->flag & ME_HIDE) efa->h= 1;
}
if(me->tface) tface++;
@@ -750,15 +764,12 @@ void make_editMesh()
}
}
- /* flush hide flags */
-
- for(eed= em->edges.first; eed; eed= eed->next) {
- if(eed->v1->h || eed->v2->h) eed->h= 1;
- else eed->h= 0;
- }
- for(efa= em->faces.first; efa; efa= efa->next) {
- if(efa->e1->h || efa->e2->h || efa->e3->h) efa->h= 1;
- else if(efa->e4 && efa->e4->h) efa->h= 1;
+ /* flush hide flags when no medge */
+ if(me->medge==NULL) {
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->v1->h || eed->v2->h) eed->h |= 1;
+ else eed->h &= ~1;
+ }
}
MEM_freeN(evlist);
@@ -1009,6 +1020,8 @@ void load_editMesh(void)
medge->flag= eed->f & SELECT;
if(eed->f2<2) medge->flag |= ME_EDGEDRAW;
if(eed->seam) medge->flag |= ME_SEAM;
+ if(eed->h & EM_FGON) medge->flag |= ME_FGON; // different defines yes
+ if(eed->h & 1) medge->flag |= ME_HIDE;
medge->crease= (char)(255.0*eed->crease);
@@ -1030,10 +1043,12 @@ void load_editMesh(void)
mface->mat_nr= efa->mat_nr;
mface->puno= efa->puno;
+
mface->flag= efa->flag;
/* bit 0 of flag is already taken for smooth... */
if(efa->f & 1) mface->flag |= ME_FACE_SEL;
else mface->flag &= ~ME_FACE_SEL;
+ if(efa->h) mface->flag |= ME_HIDE;
/* mat_nr in vertex */
if(me->totcol>1) {
diff --git a/source/blender/src/editmesh_add.c b/source/blender/src/editmesh_add.c
index 2186735ecd3..8421228fb2a 100644
--- a/source/blender/src/editmesh_add.c
+++ b/source/blender/src/editmesh_add.c
@@ -190,7 +190,11 @@ void addedgeface_mesh(void)
makeDispList(G.obedit);
return;
}
- if(amount<2 || amount>4) {
+ else if(amount > 4) {
+ //make_fgon();
+ return;
+ }
+ else if(amount<2) {
error("Incorrect number of vertices to make edge/face");
return;
}
diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c
index 263f860a7b2..3ea520cf571 100644
--- a/source/blender/src/editmesh_lib.c
+++ b/source/blender/src/editmesh_lib.c
@@ -704,6 +704,8 @@ short extrudeflag_vert(short flag)
}
eve= nextve;
}
+ // since its vertex select mode now, it also deselects higher order
+ EM_selectmode_flush();
return 1;
}
diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c
index bcfa7c303c4..7cd35e1421d 100644
--- a/source/blender/src/editmesh_mods.c
+++ b/source/blender/src/editmesh_mods.c
@@ -396,6 +396,33 @@ static int unified_findnearest(EditVert **eve, EditEdge **eed, EditFace **efa)
return (*eve || *eed || *efa);
}
+void EM_select_face_fgon(EditFace *efa, int val)
+{
+ EditMesh *em = G.editMesh;
+ short index=0;
+
+ if(efa->fgonf==0) EM_select_face(efa, val);
+ else {
+ if(efa->e1->fgoni) index= efa->e1->fgoni;
+ if(efa->e2->fgoni) index= efa->e2->fgoni;
+ if(efa->e3->fgoni) index= efa->e3->fgoni;
+ if(efa->v4 && efa->e4->fgoni) index= efa->e4->fgoni;
+
+ if(index==0) printf("wrong fgon select\n");
+
+ // select all ngon faces with index
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->fgonf) {
+ if(efa->e1->fgoni==index || efa->e2->fgoni==index ||
+ efa->e3->fgoni==index || (efa->e4 && efa->e4->fgoni==index) ) {
+ EM_select_face(efa, val);
+ }
+ }
+ }
+ }
+}
+
+
/* here actual select happens */
void mouse_mesh(void)
{
@@ -409,10 +436,10 @@ void mouse_mesh(void)
if(efa) {
if( (efa->f & SELECT)==0 ) {
- EM_select_face(efa, 1);
+ EM_select_face_fgon(efa, 1);
}
else if(G.qual & LR_SHIFTKEY) {
- EM_select_face(efa, 0);
+ EM_select_face_fgon(efa, 0);
}
}
else if(eed) {
@@ -566,6 +593,204 @@ void selectconnected_mesh(int qual)
}
+/* results in:
+ - faces having ->fgonf flag set (also for draw)
+ - edges having ->fgoni index set (for select)
+*/
+
+static float editface_area(EditFace *efa)
+{
+ if(efa->v4) return AreaQ3Dfl(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co);
+ else return AreaT3Dfl(efa->v1->co, efa->v2->co, efa->v3->co);
+}
+
+void fgon_flags()
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa, *efan, *efamax;
+ EditEdge *eed;
+ ListBase listb={NULL, NULL};
+ float size, maxsize;
+ short done, curindex= 1;
+
+ // for each face with fgon edge AND not fgon flag set
+ for(eed= em->edges.first; eed; eed= eed->next) eed->fgoni= 0; // index
+ for(efa= em->faces.first; efa; efa= efa->next) efa->fgonf= 0; // flag
+
+ // for speed & simplicity, put fgon face candidates in new listbase
+ efa= em->faces.first;
+ while(efa) {
+ efan= efa->next;
+ if( (efa->e1->h & EM_FGON) || (efa->e2->h & EM_FGON) ||
+ (efa->e3->h & EM_FGON) || (efa->e4 && (efa->e4->h & EM_FGON)) ) {
+ BLI_remlink(&em->faces, efa);
+ BLI_addtail(&listb, efa);
+ }
+ efa= efan;
+ }
+
+ // find an undone face with fgon edge
+ for(efa= listb.first; efa; efa= efa->next) {
+ if(efa->fgonf==0) {
+
+ // init this face
+ efa->fgonf= EM_FGON;
+ if(efa->e1->h & EM_FGON) efa->e1->fgoni= curindex;
+ if(efa->e2->h & EM_FGON) efa->e2->fgoni= curindex;
+ if(efa->e3->h & EM_FGON) efa->e3->fgoni= curindex;
+ if(efa->e4 && (efa->e4->h & EM_FGON)) efa->e4->fgoni= curindex;
+
+ // we search for largest face, to give facedot drawing rights
+ maxsize= editface_area(efa);
+ efamax= efa;
+
+ // now flush curendex over edges and set faceflags
+ done= 1;
+ while(done==1) {
+ done= 0;
+
+ for(efan= listb.first; efan; efan= efan->next) {
+ if(efan->fgonf==0) {
+ // if one if its edges has index set, do other too
+ if( (efan->e1->fgoni==curindex) || (efan->e2->fgoni==curindex) ||
+ (efan->e3->fgoni==curindex) || (efan->e4 && (efan->e4->fgoni==curindex)) ) {
+
+ efan->fgonf= EM_FGON;
+ if(efan->e1->h & EM_FGON) efan->e1->fgoni= curindex;
+ if(efan->e2->h & EM_FGON) efan->e2->fgoni= curindex;
+ if(efan->e3->h & EM_FGON) efan->e3->fgoni= curindex;
+ if(efan->e4 && (efan->e4->h & EM_FGON)) efan->e4->fgoni= curindex;
+
+ size= editface_area(efan);
+ if(size>maxsize) {
+ efamax= efan;
+ maxsize= size;
+ }
+ done= 1;
+ }
+ }
+ }
+ }
+
+ efamax->fgonf |= EM_FGON_DRAW;
+ curindex++;
+
+ }
+ }
+
+ // put fgon face candidates back in listbase
+ efa= listb.first;
+ while(efa) {
+ efan= efa->next;
+ BLI_remlink(&listb, efa);
+ BLI_addtail(&em->faces, efa);
+ efa= efan;
+ }
+}
+
+
+/* selected faces get hidden edges */
+void make_fgon(void)
+{
+ EditMesh *em = G.editMesh;
+ EditFace *efa;
+ EditEdge *eed;
+ EditVert *eve;
+ float *nor=NULL, dot; // reference
+ int done=0;
+
+ /* tagging edges. rule is:
+ - edge used by exactly 2 selected faces
+ - no vertices allowed with only tagged edges (return)
+ - face normals should not differ too much
+
+ */
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ eed->f1= 0; // amount of selected
+ eed->f2= 0; // amount of unselected
+ }
+
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->f & SELECT) {
+ if(nor==NULL) nor= efa->n;
+ if(efa->e1->f1 < 3) efa->e1->f1++;
+ if(efa->e2->f1 < 3) efa->e2->f1++;
+ if(efa->e3->f1 < 3) efa->e3->f1++;
+ if(efa->e4 && efa->e4->f1 < 3) efa->e4->f1++;
+ }
+ else {
+ if(efa->e1->f2 < 3) efa->e1->f2++;
+ if(efa->e2->f2 < 3) efa->e2->f2++;
+ if(efa->e3->f2 < 3) efa->e3->f2++;
+ if(efa->e4 && efa->e4->f2 < 3) efa->e4->f2++;
+ }
+ }
+ // now eed->f1 becomes tagged edge
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f1==2 && eed->f2==0) eed->f1= 1;
+ else eed->f1= 0;
+ }
+
+ // no vertices allowed with only tagged edges
+ for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f1) {
+ eed->v1->f1 |= 1;
+ eed->v2->f1 |= 1;
+ }
+ else {
+ eed->v1->f1 |= 2;
+ eed->v2->f1 |= 2;
+ }
+ }
+ for(eve= em->verts.first; eve; eve= eve->next) {
+ if(eve->f1==1) break;
+ }
+ if(eve) {
+ error("Cannot make polygon with interior vertices");
+ return;
+ }
+
+ // check co-planar
+ if(nor==NULL) {
+ error("No faces selected to make FGon");
+ return;
+ }
+ for(efa= em->faces.first; efa; efa= efa->next) {
+ if(efa->f & SELECT) {
+ dot= nor[0]*efa->n[0]+nor[1]*efa->n[1]+nor[2]*efa->n[2];
+ if(dot<0.9 && dot > -0.9) break;
+ }
+ }
+ if(efa) {
+ error("Not a set of co-planar faces to make FGon");
+ return;
+ }
+
+ // and there we go
+ for(eed= em->edges.first; eed; eed= eed->next) {
+ if(eed->f1) {
+ eed->h |= EM_FGON;
+ done= 1;
+ }
+ }
+
+ if(done==0) {
+ error("Didn't find FGon to create");
+ }
+ else {
+ Mesh *me= G.obedit->data;
+ // signal to save edges with ngon flags
+ if(!me->medge)
+ me->medge= MEM_callocN(sizeof(MEdge), "fake mesh edge");
+
+ fgon_flags(); // redo flags and indices for fgons
+
+ allqueue(REDRAWVIEW3D, 0);
+ makeDispList(G.obedit);
+ BIF_undo_push("Make FGon");
+ }
+}
/* swap is 0 or 1, if 1 it hides not selected */
@@ -591,7 +816,7 @@ void hide_mesh(int swap)
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->v1->h || eed->v2->h) {
- eed->h= 1;
+ eed->h |= 1;
eed->f &= ~SELECT;
}
else eed->h= 0;
@@ -609,9 +834,7 @@ void hide_mesh(int swap)
for(eed= em->edges.first; eed; eed= eed->next) {
if((eed->f & SELECT)!=swap) {
- eed->h= 1;
- eed->v1->h= 1;
- eed->v2->h= 1;
+ eed->h |= 1;
EM_select_edge(eed, 0);
}
}
@@ -629,11 +852,6 @@ void hide_mesh(int swap)
for(efa= em->faces.first; efa; efa= efa->next) {
if((efa->f & SELECT)!=swap) {
efa->h= 1;
- efa->e1->h= efa->e2->h= efa->e3->h= 1;
- if(efa->e4) efa->e4->h= 1;
- efa->v1->h= efa->v2->h= efa->v3->h= 1;
- if(efa->v4) efa->v4->h= 1;
-
EM_select_face(efa, 0);
}
}
@@ -663,7 +881,7 @@ void reveal_mesh(void)
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->h) {
- eed->h= 0;
+ eed->h &= ~1;
eed->f |= SELECT;
}
}
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index aa13f4e9394..e3ffb6483f4 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -637,9 +637,7 @@ void BIF_undo_push(char *str)
}
void BIF_undo(void)
-{
- extern void undo_curve_step(int step); // editcurve.c
-
+{
if(G.obedit) {
if(G.obedit->type==OB_MESH)
undo_editmode_step(1);
@@ -662,8 +660,6 @@ void BIF_undo(void)
void BIF_redo(void)
{
- extern void undo_curve_step(int step); // editcurve.c
-
if(G.obedit) {
if(G.obedit->type==OB_MESH)
undo_editmode_step(-1);