diff options
author | Diego Borghetti <bdiego@gmail.com> | 2010-07-06 23:26:38 +0400 |
---|---|---|
committer | Diego Borghetti <bdiego@gmail.com> | 2010-07-06 23:26:38 +0400 |
commit | cfc35a4d30ae03aa4a032189d72e91c5d0d17a1d (patch) | |
tree | d4d2228b52d5071f6e3f1457ed13fdf20788826f /source | |
parent | 0d8e1abff55658bd59d307f4dfc74ab724dbf1a3 (diff) |
Bring back "Sort Faces" command.
This was the old Ctrl + FKEY in object mode, now it's in
edit mode and is part of the Ctrl + FKEY menu (Faces).
I also assing this to the Ctrl + Alt + FKEY, but Matt please
check this and feel free to change (or tell me and I will change).
Still there is no "reverse" function, but I commit now to finish
in my home.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 179 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 147 |
4 files changed, 182 insertions, 147 deletions
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index a46d154cc22..1f112ec1105 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -80,6 +80,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise #include "ED_screen.h" #include "ED_transform.h" #include "ED_view3d.h" +#include "ED_object.h" #include "mesh_intern.h" @@ -7077,6 +7078,184 @@ void MESH_OT_beautify_fill(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ********************** SORT FACES ******************* */ + +static void permutate(void *list, int num, int size, int *index) +{ + void *buf; + int len; + int i; + + len = num * size; + + buf = MEM_mallocN(len, "permutate"); + memcpy(buf, list, len); + + for (i = 0; i < num; i++) { + memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size); + } + MEM_freeN(buf); +} + +/* sort faces on view axis */ +static float *face_sort_floats; +static int float_sort(const void *v1, const void *v2) +{ + float x1, x2; + + x1 = face_sort_floats[((int *) v1)[0]]; + x2 = face_sort_floats[((int *) v2)[0]]; + + if( x1 > x2 ) return 1; + else if( x1 < x2 ) return -1; + return 0; +} + + +static int sort_faces_exec(bContext *C, wmOperator *op) +{ + RegionView3D *rv3d= ED_view3d_context_rv3d(C); + View3D *v3d= CTX_wm_view3d(C); + Object *ob= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); + Mesh *me; + CustomDataLayer *layer; + int i, *index; + int event; + float reverse = 1; + // XXX int ctrl= 0; + + if(!ob) return OPERATOR_FINISHED; + if(ob->type!=OB_MESH) return OPERATOR_FINISHED; + if (!v3d) return OPERATOR_FINISHED; + + /* This operator work in Object Mode, not in edit mode. + * After talk with Cambell we agree that there is no point to port this to EditMesh right now. + * so for now, we just exit_editmode and enter_editmode at the end of this function. + */ + ED_object_exit_editmode(C, EM_FREEDATA); + + me= ob->data; + if(me->totface==0) { + ED_object_enter_editmode(C, 0); + return OPERATOR_FINISHED; + } + + event= RNA_enum_get(op->ptr, "type"); + + // XXX + //if(ctrl) + // reverse = -1; + + /* create index list */ + index= (int *)MEM_mallocN(sizeof(int) * me->totface, "sort faces"); + for (i = 0; i < me->totface; i++) { + index[i] = i; + } + + face_sort_floats = (float *) MEM_mallocN(sizeof(float) * me->totface, "sort faces float"); + + /* sort index list instead of faces itself + * and apply this permutation to all face layers + */ + if (event == 5) { + /* Random */ + for(i=0; i<me->totface; i++) { + face_sort_floats[i] = BLI_frand(); + } + qsort(index, me->totface, sizeof(int), float_sort); + } else { + MFace *mf; + float vec[3]; + float mat[4][4]; + float cur[3]; + + if (event == 1) + mul_m4_m4m4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */ + else if (event == 2) { /* sort from cursor */ + if( v3d && v3d->localvd ) { + VECCOPY(cur, v3d->cursor); + } else { + VECCOPY(cur, scene->cursor); + } + invert_m4_m4(mat, OBACT->obmat); + mul_m4_v3(mat, cur); + } + + mf= me->mface; + + for(i=0; i<me->totface; i++, mf++) { + if (event==3) { + face_sort_floats[i] = ((float)mf->mat_nr)*reverse; + } else if (event==4) { + /*selected first*/ + if (mf->flag & ME_FACE_SEL) + face_sort_floats[i] = 0.0; + else + face_sort_floats[i] = reverse; + } else { + /* find the faces center */ + add_v3_v3v3(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co); + if (mf->v4) { + add_v3_v3(vec, (me->mvert+mf->v3)->co); + add_v3_v3(vec, (me->mvert+mf->v4)->co); + mul_v3_fl(vec, 0.25f); + } else { + add_v3_v3(vec, (me->mvert+mf->v3)->co); + mul_v3_fl(vec, 1.0f/3.0f); + } /* done */ + + if (event == 1) { /* sort on view axis */ + mul_m4_v3(mat, vec); + face_sort_floats[i] = vec[2] * reverse; + } else if(event == 2) { /* distance from cursor*/ + face_sort_floats[i] = len_v3v3(cur, vec) * reverse; /* back to front */ + } + } + } + qsort(index, me->totface, sizeof(int), float_sort); + } + + MEM_freeN(face_sort_floats); + for(i = 0; i < me->fdata.totlayer; i++) { + layer = &me->fdata.layers[i]; + permutate(layer->data, me->totface, CustomData_sizeof(layer->type), index); + } + + MEM_freeN(index); + DAG_id_flush_update(ob->data, OB_RECALC_DATA); + + /* Return to editmode. */ + ED_object_enter_editmode(C, 0); +} + +void MESH_OT_sort_faces(wmOperatorType *ot) +{ + static EnumPropertyItem type_items[]= { + { 1, "VIEW_AXIS", 0, "View Axis", "" }, + { 2, "CURSOR_DISTANCE", 0, "Cursor Distance", "" }, + { 3, "MATERIAL", 0, "Material", "" }, + { 4, "SELECTION", 0, "Selection", "" }, + { 5, "RANDOMIZE", 0, "Randomize", "" }, + { 0, NULL, 0, NULL, NULL }}; + + /* identifiers */ + ot->name= "Sort Faces"; // XXX (Ctrl to reverse)%t| + ot->description= "The faces of the active Mesh Object are sorted, based on the current view."; + ot->idname= "MESH_OT_sort_faces"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= sort_faces_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + ot->prop= RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); +} + /********************** Quad/Tri Operators *************************/ static int quads_convert_to_tris_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 3e175c657f6..6db2a3f211d 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -241,6 +241,7 @@ void MESH_OT_rip(struct wmOperatorType *ot); void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); void MESH_OT_blend_from_shape(struct wmOperatorType *ot); +void MESH_OT_sort_faces(struct wmOperatorType *ot); /* ******************* mesh_data.c */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index c5ddd3547ef..1394331a191 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -113,6 +113,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_edge_flip); WM_operatortype_append(MESH_OT_faces_shade_smooth); WM_operatortype_append(MESH_OT_faces_shade_flat); + WM_operatortype_append(MESH_OT_sort_faces); WM_operatortype_append(MESH_OT_delete); @@ -273,6 +274,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_fill", FKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_beautify_fill", FKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_sort_faces", FKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_quads_convert_to_tris", TKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_edge_flip", FKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index b7a63b60318..70098e0812f 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -601,153 +601,6 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/* ********************** SORT FACES ******************* */ - -static void permutate(void *list, int num, int size, int *index) -{ - void *buf; - int len; - int i; - - len = num * size; - - buf = MEM_mallocN(len, "permutate"); - memcpy(buf, list, len); - - for (i = 0; i < num; i++) { - memcpy((char *)list + (i * size), (char *)buf + (index[i] * size), size); - } - MEM_freeN(buf); -} - -/* sort faces on view axis */ -static float *face_sort_floats; -static int float_sort(const void *v1, const void *v2) -{ - float x1, x2; - - x1 = face_sort_floats[((int *) v1)[0]]; - x2 = face_sort_floats[((int *) v2)[0]]; - - if( x1 > x2 ) return 1; - else if( x1 < x2 ) return -1; - return 0; -} - - -void sort_faces(Scene *scene, View3D *v3d) -{ - RegionView3D *rv3d= NULL; // get from context - Object *ob= OBACT; - Mesh *me; - CustomDataLayer *layer; - int i, *index; - short event; - float reverse = 1; - int ctrl= 0; // XXX - - if(!ob) return; - if(scene->obedit) return; - if(ob->type!=OB_MESH) return; - if (!v3d) return; - - me= ob->data; - if(me->totface==0) return; - - event = pupmenu( - "Sort Faces (Ctrl to reverse)%t|" - "View Axis%x1|" - "Cursor Distance%x2|" - "Material%x3|" - "Selection%x4|" - "Randomize%x5"); - - if (event==-1) return; - - if(ctrl) - reverse = -1; - -/* create index list */ - index = (int *) MEM_mallocN(sizeof(int) * me->totface, "sort faces"); - for (i = 0; i < me->totface; i++) { - index[i] = i; - } - - face_sort_floats = (float *) MEM_mallocN(sizeof(float) * me->totface, "sort faces float"); - -/* sort index list instead of faces itself - and apply this permutation to all face layers */ - - if (event == 5) { - /* Random */ - for(i=0; i<me->totface; i++) { - face_sort_floats[i] = BLI_frand(); - } - qsort(index, me->totface, sizeof(int), float_sort); - } else { - MFace *mf; - float vec[3]; - float mat[4][4]; - float cur[3]; - - if (event == 1) - mul_m4_m4m4(mat, OBACT->obmat, rv3d->viewmat); /* apply the view matrix to the object matrix */ - else if (event == 2) { /* sort from cursor */ - if( v3d && v3d->localvd ) { - VECCOPY(cur, v3d->cursor); - } else { - VECCOPY(cur, scene->cursor); - } - invert_m4_m4(mat, OBACT->obmat); - mul_m4_v3(mat, cur); - } - - mf= me->mface; - for(i=0; i<me->totface; i++, mf++) { - - if (event==3) { - face_sort_floats[i] = ((float)mf->mat_nr)*reverse; - } else if (event==4) { - /*selected first*/ - if (mf->flag & ME_FACE_SEL) face_sort_floats[i] = 0.0; - else face_sort_floats[i] = reverse; - } else { - /* find the faces center */ - add_v3_v3v3(vec, (me->mvert+mf->v1)->co, (me->mvert+mf->v2)->co); - if (mf->v4) { - add_v3_v3(vec, (me->mvert+mf->v3)->co); - add_v3_v3(vec, (me->mvert+mf->v4)->co); - mul_v3_fl(vec, 0.25f); - } else { - add_v3_v3(vec, (me->mvert+mf->v3)->co); - mul_v3_fl(vec, 1.0f/3.0f); - } /* done */ - - if (event == 1) { /* sort on view axis */ - mul_m4_v3(mat, vec); - face_sort_floats[i] = vec[2] * reverse; - } else if(event == 2) { /* distance from cursor*/ - face_sort_floats[i] = len_v3v3(cur, vec) * reverse; /* back to front */ - } - } - } - qsort(index, me->totface, sizeof(int), float_sort); - } - - MEM_freeN(face_sort_floats); - - for(i = 0; i < me->fdata.totlayer; i++) { - layer = &me->fdata.layers[i]; - permutate(layer->data, me->totface, CustomData_sizeof(layer->type), index); - } - - MEM_freeN(index); - - DAG_id_flush_update(ob->data, OB_RECALC_DATA); -} - - - /* ********************* MESH VERTEX OCTREE LOOKUP ************* */ /* important note; this is unfinished, needs better API for editmode, and custom threshold */ |