[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36417] branches/bmesh/blender/source/ blender: =bmesh= brought loop to region/region to loop back

Joseph Eagar joeedh at gmail.com
Sun May 1 22:43:55 CEST 2011


Revision: 36417
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36417
Author:   joeedh
Date:     2011-05-01 20:43:54 +0000 (Sun, 01 May 2011)
Log Message:
-----------
=bmesh= brought loop to region/region to loop back

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_iterators.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_iterators.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_iterators.c	2011-05-01 18:53:18 UTC (rev 36416)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_iterators.c	2011-05-01 20:43:54 UTC (rev 36417)
@@ -248,12 +248,15 @@
 
 	iter->firstloop = l;
 	iter->nextloop = bmesh_radial_nextloop(iter->firstloop);
+	
+	if (iter->nextloop == iter->firstloop)
+		iter->nextloop = NULL;
 }
 
 static void *loops_of_loop_step(BMIter *iter)
 {
 	BMLoop *current = iter->nextloop;
-
+	
 	if(iter->nextloop) iter->nextloop = bmesh_radial_nextloop(iter->nextloop);
 
 	if(iter->nextloop == iter->firstloop) iter->nextloop = NULL;

Modified: branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c
===================================================================
--- branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c	2011-05-01 18:53:18 UTC (rev 36416)
+++ branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c	2011-05-01 20:43:54 UTC (rev 36417)
@@ -54,6 +54,7 @@
 #include "BLI_math.h"
 #include "BLI_rand.h"
 #include "BLI_array.h"
+#include "BLI_smallhash.h"
 
 #include "BKE_context.h"
 #include "BKE_displist.h"
@@ -2217,3 +2218,231 @@
 	/* flags */
 	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
+
+
+static int region_to_loop(bContext *C, wmOperator *op)
+{
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh;
+	BMFace *f;
+	BMEdge *e;
+	BMIter iter;
+	
+	BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+		BMINDEX_SET(e, 0);
+	}
+
+	BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+		BMLoop *l1, *l2;
+		BMIter liter1, liter2;
+		
+		BM_ITER(l1, &liter1, em->bm, BM_LOOPS_OF_FACE, f) {
+			int tot=0, totsel=0;
+			
+			BM_ITER(l2, &liter2, em->bm, BM_LOOPS_OF_EDGE, l1->e) {
+				tot++;
+				totsel += BM_TestHFlag(l2->f, BM_SELECT) != 0;
+			}
+			
+			if ((tot != totsel && totsel > 0) || (totsel == 1 && tot == 1))
+				BMINDEX_SET(l1->e, 1);
+		}
+	}
+
+	EDBM_clear_flag_all(em, BM_SELECT);
+	
+	BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+		if (BMINDEX_GET(e) && !BM_TestHFlag(e, BM_HIDDEN))
+			BM_Select_Edge(em->bm, e, 1);
+	}
+	
+	WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_region_to_loop(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Region to Loop";
+	ot->idname= "MESH_OT_region_to_loop";
+
+	/* api callbacks */
+	ot->exec= region_to_loop;
+	ot->poll= ED_operator_editmesh;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int loop_find_region(BMEditMesh *em, BMLoop *l, int flag, 
+	SmallHash *fhash, BMFace ***region_out)
+{
+	BLI_array_declare(region);
+	BLI_array_declare(stack);
+	BMFace **region = NULL, *f;
+	BMFace **stack = NULL;
+	
+	BLI_array_append(stack, l->f);
+	BLI_smallhash_insert(fhash, (uintptr_t)l->f, NULL);
+	
+	while (BLI_array_count(stack) > 0) {
+		BMIter liter1, liter2;
+		BMLoop *l1, *l2;
+		
+		f = BLI_array_pop(stack);
+		BLI_array_append(region, f);
+		
+		BM_ITER(l1, &liter1, em->bm, BM_LOOPS_OF_FACE, f) {
+			if (BM_TestHFlag(l1->e, flag))
+				continue;
+			
+			BM_ITER(l2, &liter2, em->bm, BM_LOOPS_OF_EDGE, l1->e) {
+				if (BLI_smallhash_haskey(fhash, (uintptr_t)l2->f))
+					continue;
+				
+				BLI_array_append(stack, l2->f);
+				BLI_smallhash_insert(fhash, (uintptr_t)l2->f, NULL);
+			}
+		}
+	}
+	
+	BLI_array_free(stack);
+	
+	*region_out = region;
+	return BLI_array_count(region);
+}
+
+int verg_radial(const void *va, const void *vb)
+{
+	BMEdge *e1 = *((void**)va);
+	BMEdge *e2 = *((void**)vb);
+	int a, b;
+	
+	a = BM_Edge_FaceCount(e1);
+	b = BM_Edge_FaceCount(e2);
+	
+	if (a > b) return -1;
+	if (a == b) return 0;
+	if (a < b) return 1;
+	
+	return -1;
+}
+
+static int loop_find_regions(BMEditMesh *em, int selbigger)
+{
+	SmallHash visithash;
+	BMIter iter;
+	BMEdge *e, **edges=NULL;
+	BLI_array_declare(edges);
+	BMFace *f;
+	int count = 0, i;
+	
+	BLI_smallhash_init(&visithash);
+	
+	BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+		BMINDEX_SET(f, 0);
+	}
+
+	BM_ITER(e, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+		if (BM_TestHFlag(e, BM_SELECT)) {
+			BLI_array_append(edges, e);
+			BMINDEX_SET(e, 1);
+		} else {
+			BMINDEX_SET(e, 0);
+		}
+	}
+	
+	/*sort edges by radial cycle length*/
+	qsort(edges,  BLI_array_count(edges), sizeof(void*), verg_radial);
+	
+	for (i=0; i<BLI_array_count(edges); i++) {
+		BMIter liter;
+		BMLoop *l;
+		BMFace **region=NULL, **r;
+		int c, tot=0;
+		
+		e = edges[i];
+		
+		if (!BMINDEX_GET(e))
+			continue;
+		
+		BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_EDGE, e) {
+			if (BLI_smallhash_haskey(&visithash, (uintptr_t)l->f))
+				continue;
+						
+			c = loop_find_region(em, l, BM_SELECT, &visithash, &r);
+			
+			if (!region || (selbigger ? c >= tot : c < tot)) {
+				tot = c;
+				if (region) 
+					MEM_freeN(region);
+				region = r;
+			}
+		}
+		
+		if (region) {
+			int j;
+			
+			for (j=0; j<tot; j++) {
+				BMINDEX_SET(region[j], 1);
+				BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_FACE, region[j]) {
+					BMINDEX_SET(l->e, 0);
+				}
+			}
+			
+			count += tot;
+			
+			MEM_freeN(region);
+		}
+	}
+	
+	BLI_array_free(edges);
+	BLI_smallhash_release(&visithash);
+	
+	return count;
+}
+
+static int loop_to_region(bContext *C, wmOperator *op)
+{
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = ((Mesh*)obedit->data)->edit_btmesh;
+	BMIter iter;
+	BMFace *f;
+	int selbigger = RNA_boolean_get(op->ptr, "select_bigger");
+	int a, b;
+	
+	/*find the set of regions with smallest number of total faces*/
+ 	a = loop_find_regions(em, selbigger);
+	b = loop_find_regions(em, !selbigger);
+	
+	if ((a <= b) ^ selbigger) {
+		loop_find_regions(em, selbigger);
+	}
+	
+	EDBM_clear_flag_all(em, BM_SELECT);
+	
+	BM_ITER(f, &iter, em->bm, BM_FACES_OF_MESH, NULL) {
+		if (BMINDEX_GET(f) && !BM_TestHFlag(f, BM_HIDDEN)) {
+			BM_Select_Face(em->bm, f, 1);
+		}
+	}
+	
+	WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
+	return OPERATOR_FINISHED;
+}
+
+void MESH_OT_loop_to_region(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Loop to Region";
+	ot->idname= "MESH_OT_loop_to_region";
+
+	/* api callbacks */
+	ot->exec= loop_to_region;
+	ot->poll= ED_operator_editmesh;
+
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+	
+	RNA_def_boolean(ot->srna, "select_bigger", 0, "Select Bigger", "Select bigger regions instead of smaller ones");
+}

Modified: branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c
===================================================================
--- branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c	2011-05-01 18:53:18 UTC (rev 36416)
+++ branches/bmesh/blender/source/blender/editors/mesh/bmesh_tools.c	2011-05-01 20:43:54 UTC (rev 36417)
@@ -59,6 +59,7 @@
 #include "BLI_linklist.h"
 #include "BLI_heap.h"
 #include "BLI_array.h"
+#include "BLI_smallhash.h"
 
 #include "BKE_material.h"
 #include "BKE_context.h"
@@ -4327,113 +4328,6 @@
 	RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX);
 }
 
-static int region_to_loop(bContext *C, wmOperator *op)
-{
-#if 0
-	Object *obedit= CTX_data_edit_object(C);
-	EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
-	EditEdge *eed;
-	EditFace *efa;
-	int selected= 0;
-
-	for(eed=em->edges.first; eed; eed=eed->next) eed->f1 = 0;
-
-	for(efa=em->faces.first; efa; efa=efa->next){
-		if(efa->f&SELECT){
-			efa->e1->f1++;
-			efa->e2->f1++;
-			efa->e3->f1++;
-			if(efa->e4)
-				efa->e4->f1++;
-
-			selected= 1;
-		}
-	}
-
-	if(!selected)
-		return OPERATOR_CANCELLED;
-
-	EM_clear_flag_all(em, SELECT);
-
-	for(eed=em->edges.first; eed; eed=eed->next){
-		if(eed->f1 == 1) EM_select_edge(eed, 1);
-	}
-
-	em->selectmode = SCE_SELECT_EDGE;
-	EM_selectmode_set(em);
-
-	BKE_mesh_end_editmesh(obedit->data, em);
-
-	WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
-#endif
-	return OPERATOR_FINISHED;
-}
-
-void MESH_OT_region_to_loop(wmOperatorType *ot)
-{
-	/* identifiers */
-	ot->name= "Region to Loop";
-	ot->idname= "MESH_OT_region_to_loop";
-
-	/* api callbacks */
-	ot->exec= region_to_loop;
-	ot->poll= ED_operator_editmesh;
-
-	/* flags */
-	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-static int loop_to_region(bContext *C, wmOperator *op)
-{
-#if 0
-	Object *obedit= CTX_data_edit_object(C);
-	EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data);
-
-
-	EditFace *efa;
-	ListBase allcollections={NULL,NULL};
-	Collection *edgecollection;
-	int testflag;
-
-	build_edgecollection(em, &allcollections);
-
-	for(edgecollection = (Collection *)allcollections.first; edgecollection; edgecollection=edgecollection->next){
-		if(validate_loop(em, edgecollection)){
-			testflag = loop_bisect(em, edgecollection);
-			for(efa=em->faces.first; efa; efa=efa->next){
-				if(efa->f1 == testflag){
-					if(efa->f&SELECT) EM_select_face(efa, 0);
-					else EM_select_face(efa,1);
-				}
-			}
-		}
-	}
-
-	for(efa=em->faces.first; efa; efa=efa->next){ /*fix this*/
-		if(efa->f&SELECT) EM_select_face(efa,1);
-	}
-
-	freecollections(&allcollections);
-	BKE_mesh_end_editmesh(obedit->data, em);
-
-	WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
-#endif
-	return OPERATOR_FINISHED;
-}
-
-void MESH_OT_loop_to_region(wmOperatorType *ot)
-{
-	/* identifiers */
-	ot->name= "Loop to Region";
-	ot->idname= "MESH_OT_loop_to_region";
-
-	/* api callbacks */
-	ot->exec= loop_to_region;
-	ot->poll= ED_operator_editmesh;
-
-	/* flags */
-	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-}
-
 int select_by_number_vertices_exec(bContext *C, wmOperator *op)
 {
 #if 0




More information about the Bf-blender-cvs mailing list