[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46358] trunk/blender: Mesh elements sorting refactor.

Bastien Montagne montagne29 at wanadoo.fr
Sun May 6 19:15:02 CEST 2012


Revision: 46358
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46358
Author:   mont29
Date:     2012-05-06 17:14:56 +0000 (Sun, 06 May 2012)
Log Message:
-----------
Mesh elements sorting refactor.

Now only one operator. Same options for vertices, edges and faces (so adds edges sorting, and some options to vertices sorting).

Face sorting should behave as previously. However, XSortVerts won?\226?\128?\153t pack anymore selected vertices at the begining of the vert array (as it used to), if you want such behavior you?\226?\128?\153ll have to first run SortElements with Selected action.

Also added bug ref I forgot in r46354 (armature.c).

Revision Links:
--------------
    http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46354

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c
    trunk/blender/source/blender/editors/mesh/mesh_intern.h
    trunk/blender/source/blender/editors/mesh/mesh_ops.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2012-05-06 16:28:52 UTC (rev 46357)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2012-05-06 17:14:56 UTC (rev 46358)
@@ -1675,6 +1675,7 @@
         layout.operator("mesh.blend_from_shape")
         layout.operator("mesh.shape_propagate_to_all")
         layout.operator("mesh.select_vertex_path")
+        layout.operator("mesh.sort_elements")
 
 
 class VIEW3D_MT_edit_mesh_select_mode(Menu):
@@ -1750,8 +1751,7 @@
 
         layout.operator("mesh.vertices_smooth")
         layout.operator("mesh.remove_doubles")
-        layout.operator("mesh.vertices_sort")
-        layout.operator("mesh.vertices_randomize")
+        layout.operator("mesh.sort_elements", text="Sort Vertices").elements = {"VERT"}
 
         layout.operator("mesh.select_vertex_path")
 
@@ -1796,6 +1796,7 @@
         layout.operator("mesh.bevel")
         layout.operator("mesh.edge_split")
         layout.operator("mesh.bridge_edge_loops")
+        layout.operator("mesh.sort_elements", text="Sort Edges").elements = {"EDGE"}
 
         layout.separator()
 
@@ -1828,7 +1829,7 @@
         layout.operator("mesh.bevel")
         layout.operator("mesh.solidify")
         layout.operator("mesh.wireframe")
-        layout.operator("mesh.sort_faces")
+        layout.operator("mesh.sort_elements", text="Sort Faces").elements = {"FACE"}
 
         layout.separator()
 

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2012-05-06 16:28:52 UTC (rev 46357)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2012-05-06 17:14:56 UTC (rev 46358)
@@ -1464,7 +1464,7 @@
 	 * was 0.000001, causes bug [#30438] (which is same as [#27675, imho).
 	 * Reseting it to org value seems to cause no more [#23954]...
 	 *
-	 * was 0.0000000000001, caused bug [#], smaller values give unstable
+	 * was 0.0000000000001, caused bug [#31333], smaller values give unstable
 	 * roll when toggling editmode again...
 	 * No good value here, trying 0.000000001 as best compromize. :/
 	 */

Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-05-06 16:28:52 UTC (rev 46357)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2012-05-06 17:14:56 UTC (rev 46358)
@@ -66,6 +66,8 @@
 
 #include "RE_render_ext.h"
 
+#include "UI_interface.h"
+
 #include "mesh_intern.h"
 
 /* allow accumulated normals to form a new direction but don't
@@ -3659,394 +3661,578 @@
 	RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection");
 }
 
-/* qsort routines.  not sure how to make these
- * work, since we aren't using linked lists for
- * geometry anymore.  might need a sort of "swap"
- * function for bmesh elements. */
+/******************************************************************************
+ * qsort routines.
+ * Now unified, for vertices/edges/faces. */
 
-/* TODO All this section could probably use a refresh...
- *      face code works in object mode, does everything in one op, while vert uses several...
- */
+enum {
+	SRT_VIEW_ZAXIS = 1,  /* Use view Z (deep) axis. */
+	SRT_VIEW_XAXIS,      /* Use view X (left to right) axis. */
+	SRT_CURSOR_DISTANCE, /* Use distance from element to 3D cursor. */
+	SRT_MATERIAL,        /* Face only: use mat number. */
+	SRT_SELECTED,        /* Move selected elements in first, without modifying 
+	                      * relative order of selected and unselected elements. */
+	SRT_RANDOMIZE,       /* Randomize selected elements. */
+	SRT_REVERSE,         /* Reverse current order of selected elements. */
+};
 
-typedef struct xvertsort {
-	int x; /* X screen-coordinate */
-	int org_idx; /* Original index of this vertex _in the mempool_ */
-} xvertsort;
+typedef struct bmelemsort {
+	float srt; /* Sort factor */
+	int org_idx; /* Original index of this element _in its mempool_ */
+} bmelemsort;
 
-
-static int vergxco(const void *v1, const void *v2)
+static int bmelemsort_comp(const void *v1, const void *v2)
 {
-	const xvertsort *x1 = v1, *x2 = v2;
+	const bmelemsort *x1 = v1, *x2 = v2;
 
-	/* We move unchanged vertices (org_idx < 0) at the begining of the sorted list. */
-	if (x1->org_idx >= 0 && x2->org_idx >= 0)
-		return (x1->x > x2->x) - (x1->x < x2->x);
-	return (x2->org_idx < 0) - (x1->org_idx < 0);
+	return (x1->srt > x2->srt) - (x1->srt < x2->srt);
 }
 
-static void xsortvert_flag__doSetX(void *userData, BMVert *UNUSED(eve), int x, int UNUSED(y), int index)
+/* Reorders vertices/edges/faces using a given methods. Loops are not supported. */
+static void sort_bmelem_flag(bContext *C, const int types, const int flag, const int action,
+                             const int reverse, const unsigned int seed)
 {
-	xvertsort *sortblock = userData;
-
-	sortblock[index].x = x;
-}
-
-/* all verts with (flag & 'flag') are sorted */
-static void xsortvert_flag(bContext *C, int flag)
-{
+	Scene *scene = CTX_data_scene(C);
+	Object *ob = CTX_data_edit_object(C);
 	ViewContext vc;
 	BMEditMesh *em;
 	BMVert *ve;
+	BMEdge *ed;
+	BMFace *fa;
 	BMIter iter;
-	xvertsort *sortblock;
-	int *unchangedblock, *vmap;
-	int totvert, sorted = 0, unchanged = 0, i;
 
+	/* In all five elements below, 0 = vertices, 1 = edges, 2 = faces. */
+	/* Just to mark protected elements. */
+	char *pblock[3] = {NULL, NULL, NULL}, *pb;
+	bmelemsort *sblock[3] = {NULL, NULL, NULL}, *sb;
+	int *map[3] = {NULL, NULL, NULL}, *mp;
+	int totelem[3] = {0, 0, 0}, tot;
+	int affected[3] = {0, 0, 0}, aff;
+	int i, j;
+
+	if (!(types && flag && action))
+		return;
+
 	em_setup_viewcontext(C, &vc);
 	em = vc.em;
 
-	totvert = em->bm->totvert;
+	if (types & BM_VERT)
+		totelem[0] = em->bm->totvert;
+	if (types & BM_EDGE)
+		totelem[1] = em->bm->totedge;
+	if (types & BM_FACE)
+		totelem[2] = em->bm->totface;
 
-	sortblock = MEM_callocN(sizeof(xvertsort) * totvert, "xsort sorted");
-	/* Stores unchanged verts, will be reused as final old2new vert mapping... */
-	unchangedblock = MEM_callocN(sizeof(int) * totvert, "xsort unchanged");
-	BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
-		if (BM_elem_flag_test(ve, flag)) {
-			sortblock[i].org_idx = i;
-			sorted++;
+	if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) {
+		RegionView3D *rv3d = ED_view3d_context_rv3d(C);
+		float mat[4][4];
+		float fact = reverse ? -1.0 : 1.0;
+		int coidx = (action == SRT_VIEW_ZAXIS) ? 2 : 0;
+
+		mult_m4_m4m4(mat, rv3d->viewmat, ob->obmat);  /* Apply the view matrix to the object matrix. */
+
+		if (totelem[0]) {
+			pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock");
+			sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock");
+
+			BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+				if (BM_elem_flag_test(ve, flag)) {
+					float co[3];
+					mul_v3_m4v3(co, mat, ve->co);
+
+					pb[i] = FALSE;
+					sb[affected[0]].org_idx = i;
+					sb[affected[0]++].srt = co[coidx] * fact;
+				}
+				else {
+					pb[i] = TRUE;
+				}
+			}
 		}
-		else {
-			unchangedblock[unchanged++] = i;
-			sortblock[i].org_idx = -1;
+
+		if (totelem[1]) {
+			pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock");
+			sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock");
+
+			BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) {
+				if (BM_elem_flag_test(ed, flag)) {
+					float co[3];
+					mid_v3_v3v3(co, ed->v1->co, ed->v2->co);
+					mul_m4_v3(mat, co);
+
+					pb[i] = FALSE;
+					sb[affected[1]].org_idx = i;
+					sb[affected[1]++].srt = co[coidx] * fact;
+				}
+				else {
+					pb[i] = TRUE;
+				}
+			}
 		}
-	}
-/*	printf("%d verts: %d to be sorted, %d unchanged…\n", totvert, sorted, unchanged);*/
-	if (sorted == 0) {
-		MEM_freeN(sortblock);
-		MEM_freeN(unchangedblock);
-		return;
-	}
 
-	ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
-	mesh_foreachScreenVert(&vc, xsortvert_flag__doSetX, sortblock, V3D_CLIP_TEST_OFF);
+		if (totelem[2]) {
+			pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock");
+			sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock");
 
-	qsort(sortblock, totvert, sizeof(xvertsort), vergxco);
+			BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) {
+				if (BM_elem_flag_test(fa, flag)) {
+					float co[3];
+					BM_face_calc_center_mean(fa, co);
+					mul_m4_v3(mat, co);
 
-	/* Convert sortblock into an array mapping old idx to new. */
-	vmap = unchangedblock;
-	unchangedblock = NULL;
-	if (unchanged) {
-		unchangedblock = MEM_mallocN(sizeof(int) * unchanged, "xsort unchanged");
-		memcpy(unchangedblock, vmap, unchanged * sizeof(int));
+					pb[i] = FALSE;
+					sb[affected[2]].org_idx = i;
+					sb[affected[2]++].srt = co[coidx] * fact;
+				}
+				else {
+					pb[i] = TRUE;
+				}
+			}
+		}
 	}
-	for (i = totvert; i--; ) {
-		if (i < unchanged)
-			vmap[unchangedblock[i]] = i;
-		else
-			vmap[sortblock[i].org_idx] = i;
-	}
 
-	MEM_freeN(sortblock);
-	if (unchangedblock)
-		MEM_freeN(unchangedblock);
+	else if (action == SRT_CURSOR_DISTANCE) {
+		View3D *v3d = CTX_wm_view3d(C);
+		float cur[3];
+		float mat[4][4];
+		float fact = reverse ? -1.0 : 1.0;
 
-	BM_mesh_remap(em->bm, vmap, NULL, NULL);
+		if (v3d && v3d->localvd)
+			copy_v3_v3(cur, v3d->cursor);
+		else
+			copy_v3_v3(cur, scene->cursor);
+		invert_m4_m4(mat, ob->obmat);
+		mul_m4_v3(mat, cur);
 
-	MEM_freeN(vmap);
-}
+		if (totelem[0]) {
+			pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock");
+			sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock");
 
-static int edbm_vertices_sort_exec(bContext *C, wmOperator *UNUSED(op))
-{
-	xsortvert_flag(C, BM_ELEM_SELECT);
-	return OPERATOR_FINISHED;
-}
+			BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) {
+				if (BM_elem_flag_test(ve, flag)) {
+					pb[i] = FALSE;
+					sb[affected[0]].org_idx = i;
+					sb[affected[0]++].srt = len_squared_v3v3(cur, ve->co) * fact;
+				}
+				else {
+					pb[i] = TRUE;
+				}
+			}
+		}
 
-void MESH_OT_vertices_sort(wmOperatorType *ot)
-{

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list