bmeshafied the hide/reveal code. created a set of API functions for hiding/revealing elements in bmesh_marking.c. main function is BM_Hide, which can hide or reveal an element (vert/edge/face, NOT loops, obviously), and will handle any flushing necassary. also renamed BM_Is_Selected to BM_Selected, though I may get rid of that function altogether.

This commit is contained in:
Joseph Eagar
2009-08-05 06:06:58 +00:00
parent 012b419549
commit 886b613363
12 changed files with 265 additions and 307 deletions

View File

@@ -30,6 +30,10 @@
ele = BMIter_New(iter, bm, type, data); \
for ( ; ele; ele=BMIter_Step(iter))
#define BM_ITER_SELECT(ele, iter, bm, type, data)\
for (ele = BMIter_New(iter, bm, type, data); ele; ele=BMIter_Step(iter)) {\
if (BM_TestHFlag(ele, BM_HIDDEN) || !BM_TestHFlag(ele, BM_SELECT)) continue;
/*these are topological iterators.*/
#define BM_EDGES_OF_VERT 4
#define BM_FACES_OF_VERT 5

View File

@@ -8,17 +8,29 @@ typedef struct BMEditSelection
void *data;
} BMEditSelection;
/*geometry hiding code*/
void BM_Hide(BMesh *bm, void *element, int hide);
void BM_Hide_Vert(BMesh *bm, BMVert *v, int hide);
void BM_Hide_Edge(BMesh *bm, BMEdge *e, int hide);
void BM_Hide_Face(BMesh *bm, BMFace *f, int hide);
/*Selection code*/
void BM_Select(struct BMesh *bm, void *element, int select);
/*I don't use this function anywhere, been using BM_TestHFlag instead.
Need to decide either to keep it and convert everything over, or
chuck it.*/
int BM_Selected(BMesh *bm, void *element);
/*individual element select functions, BM_Select is a shortcut for these
that automatically detects which one to use*/
void BM_Select_Vert(struct BMesh *bm, struct BMVert *v, int select);
void BM_Select_Edge(struct BMesh *bm, struct BMEdge *e, int select);
void BM_Select_Face(struct BMesh *bm, struct BMFace *f, int select);
void BM_Selectmode_Set(struct BMesh *bm, int selectmode);
/*counts number of elements with flag set*/
int BM_CountFlag(struct BMesh *bm, int type, int flag);
void BM_Select(struct BMesh *bm, void *element, int select);
int BM_Is_Selected(BMesh *bm, void *element);
int BM_CountFlag(struct BMesh *bm, int type, int flag, int respectflag);
/*edit selection stuff*/
void BM_editselection_center(BMesh *bm, float *center, BMEditSelection *ese);

View File

@@ -234,7 +234,8 @@ void BMO_HeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotna
void BMO_UnHeaderFlag_Buffer(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag);
/*puts every element of type type (which is a bitmask) with header flag
flag, into a slot.*/
flag, into a slot. note: ignores hidden elements (e.g. elements with
header flag BM_HIDDEN set).*/
void BMO_HeaderFlag_To_Slot(struct BMesh *bm, struct BMOperator *op, char *slotname, int flag, int type);
/*counts number of elements inside a slot array.*/

View File

@@ -2435,13 +2435,13 @@ void esubdivideflag(int flag, float rad, int beauty, int numcuts, int seltype)
BMO_Init_Op(&subdop, BMOP_ESUBDIVIDE);
for (tot=0, bed=BMIter_New(&iter, bm, BM_EDGES, NULL); bed; bed=BMIter_Step(&iter)) {
if (BM_Is_Selected(bm, bed)) tot++;
if (BM_Selected(bm, bed)) tot++;
}
list = MEM_callocN(sizeof(void*)*tot, "vert ptr list");
for (tot=0, bed=BMIter_New(&iter, bm, BM_EDGES, NULL); bed; bed=BMIter_Step(&iter)) {
if (BM_Is_Selected(bm, bed)) list[tot++] = bed;
if (BM_Selected(bm, bed)) list[tot++] = bed;
}
BMO_Set_PntBuf(&subdop, BMOP_ESUBDIVIDE_EDGES, list, tot);

View File

@@ -392,7 +392,7 @@ void BM_Copy_Attributes(BMesh *source_mesh, BMesh *target_mesh, void *source, vo
return;
/*First we copy select*/
if(BM_Is_Selected(source_mesh, source)) BM_Select(target_mesh, target, 1);
if(BM_Selected(source_mesh, source)) BM_Select(target_mesh, target, 1);
/*Now we copy flags*/
theader->flag = sheader->flag;

View File

@@ -282,7 +282,7 @@ void BM_Selectmode_Set(BMesh *bm, int selectmode)
}
int BM_CountFlag(struct BMesh *bm, int type, int flag)
int BM_CountFlag(struct BMesh *bm, int type, int flag, int respecthide)
{
BMHeader *head;
BMIter iter;
@@ -290,16 +290,19 @@ int BM_CountFlag(struct BMesh *bm, int type, int flag)
if (type & BM_VERT) {
for (head = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); head; head=BMIter_Step(&iter)) {
if (respecthide && BM_TestHFlag(head, BM_HIDDEN)) continue;
if (head->flag & flag) tot++;
}
}
if (type & BM_EDGE) {
for (head = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL); head; head=BMIter_Step(&iter)) {
if (respecthide && BM_TestHFlag(head, BM_HIDDEN)) continue;
if (head->flag & flag) tot++;
}
}
if (type & BM_FACE) {
for (head = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL); head; head=BMIter_Step(&iter)) {
if (respecthide && BM_TestHFlag(head, BM_HIDDEN)) continue;
if (head->flag & flag) tot++;
}
}
@@ -317,7 +320,7 @@ void BM_Select(struct BMesh *bm, void *element, int select)
else if(head->type == BM_FACE) BM_Select_Face(bm, (BMFace*)element, select);
}
int BM_Is_Selected(BMesh *bm, void *element)
int BM_Selected(BMesh *bm, void *element)
{
BMHeader *head = element;
return BM_TestHFlag(head, BM_SELECT);
@@ -500,3 +503,103 @@ void BM_validate_selections(BMesh *em)
ese = nextese;
}
}
/***************** Mesh Hiding stuff *************/
#define SETHIDE(ele) hide ? BM_SetHFlag(ele, BM_HIDDEN) : BM_ClearHFlag(ele, BM_HIDDEN);
static void vert_flush_hide(BMesh *bm, BMVert *v) {
BMIter iter;
BMEdge *e;
BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
if (!BM_TestHFlag(e, BM_HIDDEN))
return;
}
BM_SetHFlag(v, BM_HIDDEN);
}
static void edge_flush_hide(BMesh *bm, BMEdge *e) {
BMIter iter;
BMFace *f;
BM_ITER(f, &iter, bm, BM_FACES_OF_EDGE, e) {
if (!BM_TestHFlag(f, BM_HIDDEN))
return;
}
BM_SetHFlag(e, BM_HIDDEN);
}
void BM_Hide_Vert(BMesh *bm, BMVert *v, int hide)
{
/*vert hiding: vert + surrounding edges and faces*/
BMIter iter, fiter;
BMEdge *e;
BMFace *f;
SETHIDE(v);
BM_ITER(e, &iter, bm, BM_EDGES_OF_VERT, v) {
SETHIDE(e);
BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, e) {
SETHIDE(f);
}
}
}
void BM_Hide_Edge(BMesh *bm, BMEdge *e, int hide)
{
BMIter iter;
BMFace *f;
BMVert *v;
/*edge hiding: faces around the edge*/
BM_ITER(f, &iter, bm, BM_FACES_OF_EDGE, e) {
SETHIDE(f);
}
SETHIDE(e);
/*hide vertices if necassary*/
vert_flush_hide(bm, e->v1);
vert_flush_hide(bm, e->v2);
}
void BM_Hide_Face(BMesh *bm, BMFace *f, int hide)
{
BMIter iter;
BMLoop *l;
/**/
SETHIDE(f);
BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
edge_flush_hide(bm, l->e);
}
BM_ITER(l, &iter, bm, BM_LOOPS_OF_FACE, f) {
vert_flush_hide(bm, l->v);
}
}
void BM_Hide(BMesh *bm, void *element, int hide)
{
BMHeader *h = element;
switch (h->type) {
case BM_VERT:
BM_Hide_Vert(bm, element, hide);
break;
case BM_EDGE:
BM_Hide_Edge(bm, element, hide);
break;
case BM_FACE:
BM_Hide_Face(bm, element, hide);
break;
}
}

View File

@@ -649,14 +649,14 @@ void BMO_HeaderFlag_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int flag,
BMOpSlot *output = BMO_GetSlot(op, slotname);
int totelement=0, i=0;
totelement = BM_CountFlag(bm, type, flag);
totelement = BM_CountFlag(bm, type, flag, 1);
if(totelement){
alloc_slot_buffer(op, slotname, totelement);
if (type & BM_VERT) {
for (e = BMIter_New(&elements, bm, BM_VERTS_OF_MESH, bm); e; e = BMIter_Step(&elements)) {
if(e->flag & flag) {
if(!BM_TestHFlag(e, BM_HIDDEN) && BM_TestHFlag(e, flag)) {
((BMHeader**)output->data.p)[i] = e;
i++;
}
@@ -665,7 +665,7 @@ void BMO_HeaderFlag_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int flag,
if (type & BM_EDGE) {
for (e = BMIter_New(&elements, bm, BM_EDGES_OF_MESH, bm); e; e = BMIter_Step(&elements)) {
if(e->flag & flag){
if(!BM_TestHFlag(e, BM_HIDDEN) && BM_TestHFlag(e, flag)) {
((BMHeader**)output->data.p)[i] = e;
i++;
}
@@ -674,7 +674,7 @@ void BMO_HeaderFlag_To_Slot(BMesh *bm, BMOperator *op, char *slotname, int flag,
if (type & BM_FACE) {
for (e = BMIter_New(&elements, bm, BM_FACES_OF_MESH, bm); e; e = BMIter_Step(&elements)) {
if(e->flag & flag){
if(!BM_TestHFlag(e, BM_HIDDEN) && BM_TestHFlag(e, flag)) {
((BMHeader**)output->data.p)[i] = e;
i++;
}

View File

@@ -1580,7 +1580,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
int i, tot;
tot = 0;
BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
BM_ITER_SELECT(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL)
if (BM_TestHFlag(v, BM_SELECT)) {
V_GROW(verts);
verts[tot++] = v;

View File

@@ -336,6 +336,7 @@ void MESH_OT_subdivs(wmOperatorType *ot)
/* will use vertex normals for extrusion directions, so *nor is unaffected */
short EDBM_Extrude_face_indiv(BMEditMesh *em, short flag, float *nor)
{
return 'g';
#if 0
EditVert *eve, *v1, *v2, *v3, *v4;
EditEdge *eed;
@@ -899,11 +900,9 @@ static int dupli_extrude_cursor(bContext *C, wmOperator *op, wmEvent *event)
INIT_MINMAX(min, max);
BM_ITER(v1, &iter, vc.em->bm, BM_VERTS_OF_MESH, NULL) {
if(BM_TestHFlag(v1, BM_SELECT)) {
DO_MINMAX(v1->co, min, max);
done= 1;
}
BM_ITER_SELECT(v1, &iter, vc.em->bm, BM_VERTS_OF_MESH, NULL)
DO_MINMAX(v1->co, min, max);
done= 1;
}
/* call extrude? */
@@ -1223,21 +1222,13 @@ static int editbmesh_mark_seam(bContext *C, wmOperator *op)
}
if(clear) {
BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) {
if (BM_TestHFlag(eed, BM_HIDDEN) == 0 &&
BM_TestHFlag(eed, BM_SELECT) != 0)
{
BM_ClearHFlag(eed, BM_SEAM);
}
BM_ITER_SELECT(eed, &iter, bm, BM_EDGES_OF_MESH, NULL)
BM_ClearHFlag(eed, BM_SEAM);
}
}
else {
BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) {
if (BM_TestHFlag(eed, BM_HIDDEN) == 0 &&
BM_TestHFlag(eed, BM_SELECT) != 0)
{
BM_SetHFlag(eed, BM_SEAM);
}
BM_ITER_SELECT(eed, &iter, bm, BM_EDGES_OF_MESH, NULL)
BM_SetHFlag(eed, BM_SEAM);
}
}
@@ -1280,20 +1271,12 @@ static int editbmesh_mark_sharp(bContext *C, wmOperator *op)
}
if(!clear) {
BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) {
if (BM_TestHFlag(eed, BM_HIDDEN) == 0 &&
BM_TestHFlag(eed, BM_SELECT) != 0)
{
BM_SetHFlag(eed, BM_SHARP);
}
BM_ITER_SELECT(eed, &iter, bm, BM_EDGES_OF_MESH, NULL)
BM_SetHFlag(eed, BM_SHARP);
}
} else {
BM_ITER(eed, &iter, bm, BM_EDGES_OF_MESH, NULL) {
if (BM_TestHFlag(eed, BM_HIDDEN) == 0 &&
BM_TestHFlag(eed, BM_SELECT) != 0)
{
BM_ClearHFlag(eed, BM_SHARP);
}
BM_ITER_SELECT(eed, &iter, bm, BM_EDGES_OF_MESH, NULL)
BM_ClearHFlag(eed, BM_SHARP);
}
}
@@ -1497,7 +1480,6 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
BMOperator bmop;
BMOIter siter;
BMEdge *eed;
BMFace *efa;
BMIter iter;
int ccw = RNA_int_get(op->ptr, "direction") == 1; // direction == 2 when clockwise and ==1 for counter CW.
short edgeCount = 0;
@@ -1510,8 +1492,11 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
/*first see if we have two adjacent faces*/
BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
if (BM_Edge_FaceCount(eed) == 2) {
if (BM_TestHFlag(eed->loop->f, BM_SELECT) && BM_TestHFlag(((BMLoop*)eed->loop->radial.next->data)->f, BM_SELECT))
if ((BM_TestHFlag(eed->loop->f, BM_SELECT) && BM_TestHFlag(((BMLoop*)eed->loop->radial.next->data)->f, BM_SELECT))
&& !(BM_TestHFlag(eed->loop->f, BM_HIDDEN) || BM_TestHFlag(((BMLoop*)eed->loop->radial.next->data)->f, BM_HIDDEN)))
{
break;
}
}
}
@@ -1523,7 +1508,7 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
}
if (!eed) {
BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
BM_ITER_SELECT(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL)
if (BM_TestHFlag(eed, BM_SELECT))
break;
}
@@ -1543,58 +1528,6 @@ static int edge_rotate_selected(bContext *C, wmOperator *op)
if (!EDBM_FinishOp(em, &bmop, op, 1))
return OPERATOR_CANCELLED;
#if 0
/*clear new flag for new edges, count selected edges */
for(eed= em->edges.first; eed; eed= eed->next) {
eed->f1= 0;
eed->f2 &= ~2;
if(eed->f & SELECT) edgeCount++;
}
if(edgeCount>1) {
/* more selected edges, check faces */
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->f & SELECT) {
efa->e1->f1++;
efa->e2->f1++;
efa->e3->f1++;
if(efa->e4) efa->e4->f1++;
}
}
edgeCount= 0;
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->f1==2) edgeCount++;
}
if(edgeCount==1) {
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->f1==2) {
edge_rotate(em, op, eed,dir);
break;
}
}
}
else
{
BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
}
else if(edgeCount==1) {
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->f & SELECT) {
EM_select_edge(eed, 0);
edge_rotate(em, op, eed,dir);
break;
}
}
}
else {
BKE_report(op->reports, RPT_ERROR, "Select one edge or two adjacent faces");
BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_CANCELLED;
}
#endif
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
@@ -1617,3 +1550,115 @@ void MESH_OT_edge_rotate(wmOperatorType *ot)
/* props */
RNA_def_enum(ot->srna, "direction", direction_items, DIRECTION_CW, "direction", "direction to rotate edge around.");
}
/* swap is 0 or 1, if 1 it hides not selected */
void EDBM_hide_mesh(BMEditMesh *em, int swap)
{
BMIter iter;
BMHeader *h;
int itermode;
if(em==NULL) return;
if (em->selectmode & SCE_SELECT_VERTEX)
itermode = BM_VERTS_OF_MESH;
else if (em->selectmode & SCE_SELECT_EDGE)
itermode = BM_EDGES_OF_MESH;
else
itermode = BM_FACES_OF_MESH;
BM_ITER(h, &iter, em->bm, itermode, NULL) {
if (BM_TestHFlag(h, BM_SELECT) ^ swap)
BM_Hide(em->bm, h, 1);
}
/*original hide flushing comment (OUTDATED):
hide happens on least dominant select mode, and flushes up, not down! (helps preventing errors in subsurf) */
/* - vertex hidden, always means edge is hidden too
- edge hidden, always means face is hidden too
- face hidden, only set face hide
- then only flush back down what's absolute hidden
*/
}
static int hide_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
EDBM_hide_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
return OPERATOR_FINISHED;
}
void MESH_OT_hide(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Hide Selection";
ot->idname= "MESH_OT_hide";
/* api callbacks */
ot->exec= hide_mesh_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected.");
}
void EDBM_reveal_mesh(BMEditMesh *em)
{
BMIter iter;
BMHeader *ele;
int i, types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
int sels[3] = {1, !(em->selectmode & SCE_SELECT_VERTEX), !(em->selectmode & SCE_SELECT_VERTEX | SCE_SELECT_EDGE)};
for (i=0; i<3; i++) {
BM_ITER(ele, &iter, em->bm, types[i], NULL) {
if (BM_TestHFlag(ele, BM_HIDDEN)) {
BM_Hide(em->bm, ele, 0);
if (sels[i])
BM_Select(em->bm, ele, 1);
}
}
}
EDBM_selectmode_flush(em);
}
static int reveal_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
EDBM_reveal_mesh(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
return OPERATOR_FINISHED;
}
void MESH_OT_reveal(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Reveal Hidden";
ot->idname= "MESH_OT_reveal";
/* api callbacks */
ot->exec= reveal_mesh_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}

View File

@@ -707,14 +707,3 @@ int EDBM_texFaceCheck(BMEditMesh *em)
/* some of these checks could be a touch overkill */
return em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY);
}
void EDBM_hide_mesh(BMEditMesh *em, int swap)
{
//BMESH_TODO
}
void EDBM_reveal_mesh(BMEditMesh *em)
{
//BMESH_TODO
}

View File

@@ -834,7 +834,7 @@ static int knife_cut_exec(bContext *C, wmOperator *op)
i = 0;
/*store percentage of edge cut for KNIFE_EXACT here.*/
for (be=BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be=BMIter_Step(&iter)) {
if( BM_Is_Selected(bm, be) ) {
if( BM_Selected(bm, be) ) {
isect= bm_seg_intersect(be, curve, len, mode, gh, &isected);
if (isect != 0.0f) {

View File

@@ -1902,202 +1902,6 @@ void selectconnected_mesh_all(EditMesh *em)
/* ************************* */
/* swap is 0 or 1, if 1 it hides not selected */
void EM_hide_mesh(EditMesh *em, int swap)
{
EditVert *eve;
EditEdge *eed;
EditFace *efa;
int a;
if(em==NULL) return;
/* hide happens on least dominant select mode, and flushes up, not down! (helps preventing errors in subsurf) */
/* - vertex hidden, always means edge is hidden too
- edge hidden, always means face is hidden too
- face hidden, only set face hide
- then only flush back down what's absolute hidden
*/
if(em->selectmode & SCE_SELECT_VERTEX) {
for(eve= em->verts.first; eve; eve= eve->next) {
if((eve->f & SELECT)!=swap) {
eve->f &= ~SELECT;
eve->h= 1;
}
}
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->v1->h || eed->v2->h) {
eed->h |= 1;
eed->f &= ~SELECT;
}
}
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->e1->h & 1 || efa->e2->h & 1 || efa->e3->h & 1 || (efa->e4 && efa->e4->h & 1)) {
efa->h= 1;
efa->f &= ~SELECT;
}
}
}
else if(em->selectmode & SCE_SELECT_EDGE) {
for(eed= em->edges.first; eed; eed= eed->next) {
if((eed->f & SELECT)!=swap) {
eed->h |= 1;
EM_select_edge(eed, 0);
}
}
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->e1->h & 1 || efa->e2->h & 1 || efa->e3->h & 1 || (efa->e4 && efa->e4->h & 1)) {
efa->h= 1;
efa->f &= ~SELECT;
}
}
}
else {
for(efa= em->faces.first; efa; efa= efa->next) {
if((efa->f & SELECT)!=swap) {
efa->h= 1;
EM_select_face(efa, 0);
}
}
}
/* flush down, only whats 100% hidden */
for(eve= em->verts.first; eve; eve= eve->next) eve->f1= 0;
for(eed= em->edges.first; eed; eed= eed->next) eed->f1= 0;
if(em->selectmode & SCE_SELECT_FACE) {
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->h) a= 1; else a= 2;
efa->e1->f1 |= a;
efa->e2->f1 |= a;
efa->e3->f1 |= a;
if(efa->e4) efa->e4->f1 |= a;
/* When edges are not delt with in their own loop, we need to explicitly re-selct select edges that are joined to unselected faces */
if (swap && (em->selectmode == SCE_SELECT_FACE) && (efa->f & SELECT)) {
EM_select_face(efa, 1);
}
}
}
if(em->selectmode >= SCE_SELECT_EDGE) {
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->f1==1) eed->h |= 1;
if(eed->h & 1) a= 1; else a= 2;
eed->v1->f1 |= a;
eed->v2->f1 |= a;
}
}
if(em->selectmode >= SCE_SELECT_VERTEX) {
for(eve= em->verts.first; eve; eve= eve->next) {
if(eve->f1==1) eve->h= 1;
}
}
em->totedgesel= em->totfacesel= em->totvertsel= 0;
// if(EM_texFaceCheck())
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
}
static int hide_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
EM_hide_mesh(em, RNA_boolean_get(op->ptr, "unselected"));
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_FINISHED;
}
void MESH_OT_hide(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Hide Selection";
ot->idname= "MESH_OT_hide";
/* api callbacks */
ot->exec= hide_mesh_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/* props */
RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected.");
}
void EM_reveal_mesh(EditMesh *em)
{
EditVert *eve;
EditEdge *eed;
EditFace *efa;
if(em==NULL) return;
for(eve= em->verts.first; eve; eve= eve->next) {
if(eve->h) {
eve->h= 0;
eve->f |= SELECT;
}
}
for(eed= em->edges.first; eed; eed= eed->next) {
if(eed->h & 1) {
eed->h &= ~1;
if(em->selectmode & SCE_SELECT_VERTEX);
else EM_select_edge(eed, 1);
}
}
for(efa= em->faces.first; efa; efa= efa->next) {
if(efa->h) {
efa->h= 0;
if(em->selectmode & (SCE_SELECT_EDGE|SCE_SELECT_VERTEX));
else EM_select_face(efa, 1);
}
}
EM_fgon_flags(em); /* redo flags and indices for fgons */
EM_selectmode_flush(em);
// if (EM_texFaceCheck())
// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
}
static int reveal_mesh_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
EM_reveal_mesh(em);
WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
BKE_mesh_end_editmesh(obedit->data, em);
return OPERATOR_FINISHED;
}
void MESH_OT_reveal(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Reveal Hidden";
ot->idname= "MESH_OT_reveal";
/* api callbacks */
ot->exec= reveal_mesh_exec;
ot->poll= ED_operator_editmesh;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
int select_by_number_vertices_exec(bContext *C, wmOperator *op)
{
Object *obedit= CTX_data_edit_object(C);