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
diff options
context:
space:
mode:
authorDiego Borghetti <bdiego@gmail.com>2010-07-06 23:26:38 +0400
committerDiego Borghetti <bdiego@gmail.com>2010-07-06 23:26:38 +0400
commitcfc35a4d30ae03aa4a032189d72e91c5d0d17a1d (patch)
treed4d2228b52d5071f6e3f1457ed13fdf20788826f /source/blender
parent0d8e1abff55658bd59d307f4dfc74ab724dbf1a3 (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/blender')
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c179
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c2
-rw-r--r--source/blender/editors/mesh/meshtools.c147
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 */