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.
This commit is contained in:
2010-07-06 19:26:38 +00:00
parent 0d8e1abff5
commit cfc35a4d30
5 changed files with 183 additions and 147 deletions

View File

@@ -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 */