forked from bartvdbraak/blender
select nth (face/edge/vertex) - depending on which was last selected, useful for colapsing every other edge for eg.
This commit is contained in:
parent
8c72e18354
commit
d74bbcdd85
@ -456,6 +456,7 @@ class VIEW3D_MT_select_edit_mesh(bpy.types.Menu):
|
||||
layout.separator()
|
||||
|
||||
layout.operator("mesh.select_random", text="Random...")
|
||||
layout.operator("mesh.select_nth", text="Select Nth...")
|
||||
layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
|
||||
layout.operator("mesh.faces_select_linked_flat", text="Linked Flat Faces")
|
||||
layout.operator("mesh.faces_select_interior", text="Interior Faces")
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user