From d74bbcdd852da9a17a6cf088469ebd3eb2167a9a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 22 Dec 2009 19:01:51 +0000 Subject: select nth (face/edge/vertex) - depending on which was last selected, useful for colapsing every other edge for eg. --- source/blender/editors/include/ED_mesh.h | 2 + source/blender/editors/mesh/editmesh_lib.c | 230 ++++++++++++++++++++++++++++ source/blender/editors/mesh/editmesh_mods.c | 43 ++++++ source/blender/editors/mesh/mesh_intern.h | 1 + source/blender/editors/mesh/mesh_ops.c | 1 + 5 files changed, 277 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index aab364bf686..174447c0f9f 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -150,6 +150,8 @@ void EM_free_data_layer(struct EditMesh *em, struct CustomData *data, int type) void EM_make_hq_normals(struct EditMesh *em); void EM_solidify(struct EditMesh *em, float dist); +int EM_deselect_nth(struct EditMesh *em, int nth); + /* editmesh_mods.c */ extern unsigned int em_vertoffs, em_solidoffs, em_wireoffs; diff --git a/source/blender/editors/mesh/editmesh_lib.c b/source/blender/editors/mesh/editmesh_lib.c index 1b90dbc3902..d99765bd199 100644 --- a/source/blender/editors/mesh/editmesh_lib.c +++ b/source/blender/editors/mesh/editmesh_lib.c @@ -2447,3 +2447,233 @@ void EM_solidify(EditMesh *em, float dist) MEM_freeN(vert_angles); } + +/* not that optimal!, should be nicer with bmesh */ +static void tag_face_edges(EditFace *efa) +{ + if(efa->v4) + efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= efa->e4->tmp.l= 1; + else + efa->e1->tmp.l= efa->e2->tmp.l= efa->e3->tmp.l= 1; +} +static int tag_face_edges_test(EditFace *efa) +{ + if(efa->v4) + return (efa->e1->tmp.l || efa->e2->tmp.l || efa->e3->tmp.l || efa->e4->tmp.l) ? 1:0; + else + return (efa->e1->tmp.l || efa->e2->tmp.l || efa->e3->tmp.l) ? 1:0; +} + +void em_deselect_nth_face(EditMesh *em, int nth, EditFace *efa_act) +{ + EditFace *efa; + EditEdge *eed; + int ok= 1; + + if(efa_act==NULL) { + return; + } + + /* to detect loose edges, we put f2 flag on 1 */ + for(eed= em->edges.first; eed; eed= eed->next) { + eed->tmp.l= 0; + } + + for (efa= em->faces.first; efa; efa= efa->next) { + efa->tmp.l = 0; + } + + efa_act->tmp.l = 1; + + while(ok) { + ok = 0; + + for (efa= em->faces.first; efa; efa= efa->next) { + if(efa->tmp.l==1) { /* initialize */ + tag_face_edges(efa); + } + + if(efa->tmp.l) + efa->tmp.l++; + } + + for (efa= em->faces.first; efa; efa= efa->next) { + if(efa->tmp.l==0 && tag_face_edges_test(efa)) { + efa->tmp.l= 1; + ok = 1; /* keep looping */ + } + } + } + + for (efa= em->faces.first; efa; efa= efa->next) { + if(efa->tmp.l > 0 && efa->tmp.l % nth) { + EM_select_face(efa, 0); + } + } + for (efa= em->faces.first; efa; efa= efa->next) { + if(efa->f & SELECT) { + EM_select_face(efa, 1); + } + } + + EM_nvertices_selected(em); + EM_nedges_selected(em); + EM_nfaces_selected(em); +} + +/* not that optimal!, should be nicer with bmesh */ +static void tag_edge_verts(EditEdge *eed) +{ + eed->v1->tmp.l= eed->v2->tmp.l= 1; +} +static int tag_edge_verts_test(EditEdge *eed) +{ + return (eed->v1->tmp.l || eed->v2->tmp.l) ? 1:0; +} + +void em_deselect_nth_edge(EditMesh *em, int nth, EditEdge *eed_act) +{ + EditEdge *eed; + EditVert *eve; + int ok= 1; + + if(eed_act==NULL) { + return; + } + + for(eve= em->verts.first; eve; eve= eve->next) { + eve->tmp.l= 0; + } + + for (eed= em->edges.first; eed; eed= eed->next) { + eed->tmp.l = 0; + } + + eed_act->tmp.l = 1; + + while(ok) { + ok = 0; + + for (eed= em->edges.first; eed; eed= eed->next) { + if(eed->tmp.l==1) { /* initialize */ + tag_edge_verts(eed); + } + + if(eed->tmp.l) + eed->tmp.l++; + } + + for (eed= em->edges.first; eed; eed= eed->next) { + if(eed->tmp.l==0 && tag_edge_verts_test(eed)) { + eed->tmp.l= 1; + ok = 1; /* keep looping */ + } + } + } + + for (eed= em->edges.first; eed; eed= eed->next) { + if(eed->tmp.l > 0 && eed->tmp.l % nth) { + EM_select_edge(eed, 0); + } + } + for (eed= em->edges.first; eed; eed= eed->next) { + if(eed->f & SELECT) { + EM_select_edge(eed, 1); + } + } + + { + /* grr, should be a function */ + EditFace *efa; + for (efa= em->faces.first; efa; efa= efa->next) { + if(efa->v4) { + if(efa->e1->f & efa->e2->f & efa->e3->f & efa->e4->f & SELECT ); + else efa->f &= ~SELECT; + } + else { + if(efa->e1->f & efa->e2->f & efa->e3->f & SELECT ); + else efa->f &= ~SELECT; + } + } + } + + EM_nvertices_selected(em); + EM_nedges_selected(em); + EM_nfaces_selected(em); +} + +void em_deselect_nth_vert(EditMesh *em, int nth, EditVert *eve_act) +{ + EditVert *eve; + EditEdge *eed; + int ok= 1; + + if(eve_act==NULL) { + return; + } + + for (eve= em->verts.first; eve; eve= eve->next) { + eve->tmp.l = 0; + } + + eve_act->tmp.l = 1; + + while(ok) { + ok = 0; + + for (eve= em->verts.first; eve; eve= eve->next) { + if(eve->tmp.l) + eve->tmp.l++; + } + + for (eed= em->edges.first; eed; eed= eed->next) { + if(eed->v1->tmp.l==2 && eed->v2->tmp.l==0) { /* initialize */ + eed->v2->tmp.l= 1; + ok = 1; /* keep looping */ + } + else if(eed->v2->tmp.l==2 && eed->v1->tmp.l==0) { /* initialize */ + eed->v1->tmp.l= 1; + ok = 1; /* keep looping */ + } + } + } + + for (eve= em->verts.first; eve; eve= eve->next) { + if(eve->tmp.l > 0 && eve->tmp.l % nth) { + eve->f &= ~SELECT; + } + } + + EM_deselect_flush(em); + + EM_nvertices_selected(em); + // EM_nedges_selected(em); // flush does these + // EM_nfaces_selected(em); // flush does these +} + +int EM_deselect_nth(EditMesh *em, int nth) +{ + EditSelection *ese; + ese = ((EditSelection*)em->selected.last); + if(ese) { + if(ese->type == EDITVERT) { + em_deselect_nth_vert(em, nth, (EditVert*)ese->data); + return 1; + } + + if(ese->type == EDITEDGE) { + em_deselect_nth_edge(em, nth, (EditEdge*)ese->data); + return 1; + } + } + else { + EditFace *efa_act = EM_get_actFace(em, 0); + if(efa_act) { + em_deselect_nth_face(em, nth, efa_act); + return 1; + } + } + + return 0; +} + diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index d1dde75771d..827b28f954b 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -2081,6 +2081,11 @@ static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring EM_selectmode_flush(em); // if (EM_texFaceCheck()) + /* sets as active, useful for other tools */ + if(select && em->selectmode & SCE_SELECT_EDGE) { + EM_store_selection(em, eed, EDITEDGE); + } + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); } } @@ -4535,3 +4540,41 @@ void MESH_OT_solidify(wmOperatorType *ot) prop= RNA_def_float(ot->srna, "thickness", 0.01f, -FLT_MAX, FLT_MAX, "thickness", "", -10.0f, 10.0f); RNA_def_property_ui_range(prop, -10, 10, 0.1, 4); } + +static int mesh_select_nth_exec(bContext *C, wmOperator *op) +{ + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); + int nth = RNA_int_get(op->ptr, "nth"); + + if(EM_deselect_nth(em, nth) == 0) { + BKE_report(op->reports, RPT_ERROR, "Mesh has no active vert/edge/face."); + return OPERATOR_CANCELLED; + } + + BKE_mesh_end_editmesh(obedit->data, em); + + DAG_id_flush_update(obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + + +void MESH_OT_select_nth(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select Nth"; + ot->description= ""; + ot->idname= "MESH_OT_select_nth"; + + /* api callbacks */ + ot->exec= mesh_select_nth_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); +} + diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 7b7257ae9cb..e8ec85d8bd0 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -164,6 +164,7 @@ void MESH_OT_mark_sharp(struct wmOperatorType *ot); void MESH_OT_vertices_smooth(struct wmOperatorType *ot); void MESH_OT_flip_normals(struct wmOperatorType *ot); void MESH_OT_solidify(struct wmOperatorType *ot); +void MESH_OT_select_nth(struct wmOperatorType *ot); extern EditEdge *findnearestedge(ViewContext *vc, int *dist); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index af25dbda16b..11b5f3a9031 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -152,6 +152,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_loopcut); WM_operatortype_append(MESH_OT_solidify); + WM_operatortype_append(MESH_OT_select_nth); } int ED_operator_editmesh_face_select(bContext *C) -- cgit v1.2.3