| 
									
										
										
										
											2009-01-21 07:03:39 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bmesh.h"
 | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | #include "mesh_intern.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-21 07:03:39 +00:00
										 |  |  | #include "bmesh_private.h"
 | 
					
						
							|  |  |  | #include "BLI_arithb.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2009-01-21 07:03:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define FACE_MARK	1
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | #define FACE_ORIG	2
 | 
					
						
							|  |  |  | #define FACE_NEW	4
 | 
					
						
							| 
									
										
										
										
											2009-03-09 09:52:32 +00:00
										 |  |  | #define EDGE_MARK	1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define VERT_MARK	1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int check_hole_in_region(BMesh *bm, BMFace *f) { | 
					
						
							|  |  |  | 	BMWalker regwalker; | 
					
						
							|  |  |  | 	BMIter liter2; | 
					
						
							|  |  |  | 	BMLoop *l2, *l3; | 
					
						
							|  |  |  | 	BMFace *f2; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/*checks if there are any unmarked boundary edges in the face region*/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BMW_Init(®walker, bm, BMW_ISLAND, FACE_MARK); | 
					
						
							|  |  |  | 	f2 = BMW_Begin(®walker, f); | 
					
						
							|  |  |  | 	for (; f2; f2=BMW_Step(®walker)) { | 
					
						
							|  |  |  | 		l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2); | 
					
						
							|  |  |  | 		for (; l2; l2=BMIter_Step(&liter2)) {			 | 
					
						
							|  |  |  | 			l3 = bmesh_radial_nextloop(l2); | 
					
						
							|  |  |  | 			if (BMO_TestFlag(bm, l3->f, FACE_MARK)  | 
					
						
							|  |  |  | 			    != BMO_TestFlag(bm, l2->f, FACE_MARK)) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (!BMO_TestFlag(bm, l2->e, EDGE_MARK)) { | 
					
						
							|  |  |  | 					return 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	BMW_End(®walker); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-15 01:02:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | void dissolvefaces_exec(BMesh *bm, BMOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-21 07:03:39 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	BMOIter oiter; | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 	BMIter liter, liter2, liter3; | 
					
						
							|  |  |  | 	BMLoop *l, *l2, *l3; | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 	BMFace *f, *f2, *nf = NULL; | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	V_DECLARE(region); | 
					
						
							|  |  |  | 	V_DECLARE(regions); | 
					
						
							|  |  |  | 	BMLoop ***regions = NULL; | 
					
						
							|  |  |  | 	BMLoop **region = NULL; | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 	BMWalker regwalker; | 
					
						
							|  |  |  | 	int i, j, fcopied; | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 	BMO_Flag_Buffer(bm, op, "faces", FACE_MARK); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/*collect regions*/ | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 	f = BMO_IterNew(&oiter, bm, op, "faces"); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	for (; f; f=BMO_IterStep(&oiter)) { | 
					
						
							|  |  |  | 		if (!BMO_TestFlag(bm, f, FACE_MARK)) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 		V_RESET(region); | 
					
						
							|  |  |  | 		region = NULL; /*forces different allocation*/ | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 		/*yay, walk!*/ | 
					
						
							|  |  |  | 		BMW_Init(®walker, bm, BMW_ISLAND, FACE_MARK); | 
					
						
							|  |  |  | 		f2 = BMW_Begin(®walker, f); | 
					
						
							|  |  |  | 		for (; f2; f2=BMW_Step(®walker)) { | 
					
						
							|  |  |  | 			l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2); | 
					
						
							|  |  |  | 			for (; l2; l2=BMIter_Step(&liter2)) { | 
					
						
							|  |  |  | 				l3 = BMIter_New(&liter3, bm, BM_LOOPS_OF_LOOP, l2); | 
					
						
							|  |  |  | 				for (; l3; l3=BMIter_Step(&liter3)) { | 
					
						
							|  |  |  | 					if (!BMO_TestFlag(bm, l3->f, FACE_MARK)) { | 
					
						
							|  |  |  | 						V_GROW(region); | 
					
						
							|  |  |  | 						region[V_COUNT(region)-1] = l2; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 				if (bmesh_radial_nextloop(l2) == l2) { | 
					
						
							|  |  |  | 					V_GROW(region); | 
					
						
							|  |  |  | 					region[V_COUNT(region)-1] = l2; | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 		}				 | 
					
						
							|  |  |  | 		BMW_End(®walker); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BMW_Init(®walker, bm, BMW_ISLAND, FACE_MARK); | 
					
						
							|  |  |  | 		f2 = BMW_Begin(®walker, f); | 
					
						
							|  |  |  | 		for (; f2; f2=BMW_Step(®walker)) { | 
					
						
							|  |  |  | 			BMO_ClearFlag(bm, f2, FACE_MARK); | 
					
						
							|  |  |  | 			BMO_SetFlag(bm, f2, FACE_ORIG); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BMW_End(®walker); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (BMO_HasError(bm)) { | 
					
						
							|  |  |  | 			BMO_ClearStack(bm); | 
					
						
							|  |  |  | 			BMO_RaiseError(bm, op, BMERR_DISSOLVEFACES_FAILED, NULL); | 
					
						
							|  |  |  | 			goto cleanup; | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		V_GROW(region); | 
					
						
							|  |  |  | 		V_GROW(regions); | 
					
						
							|  |  |  | 		regions[V_COUNT(regions)-1] = region; | 
					
						
							|  |  |  | 		region[V_COUNT(region)-1] = NULL; | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	for (i=0; i<V_COUNT(regions); i++) { | 
					
						
							|  |  |  | 		BMEdge **edges = NULL; | 
					
						
							|  |  |  | 		V_DECLARE(edges); | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 		region = regions[i]; | 
					
						
							|  |  |  | 		for (j=0; region[j]; j++) { | 
					
						
							|  |  |  | 			V_GROW(edges); | 
					
						
							|  |  |  | 			edges[V_COUNT(edges)-1] = region[j]->e; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2009-03-14 02:52:16 +00:00
										 |  |  | 		if (!region[0]) { | 
					
						
							|  |  |  | 			BMO_RaiseError(bm, op, BMERR_DISSOLVEFACES_FAILED,  | 
					
						
							|  |  |  | 			                "Could not find boundary of dissolve region"); | 
					
						
							|  |  |  | 			goto cleanup; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 15:15:17 +00:00
										 |  |  | 		if (region[0]->e->v1 == region[0]->v) | 
					
						
							|  |  |  | 			f= BM_Make_Ngon(bm, region[0]->e->v1, region[0]->e->v2,  edges, j, 1); | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			f= BM_Make_Ngon(bm, region[0]->e->v2, region[0]->e->v1,  edges, j, 1); | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		V_FREE(edges); | 
					
						
							| 
									
										
										
										
											2009-03-09 15:15:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (!f) { | 
					
						
							|  |  |  | 			BMO_RaiseError(bm, op, BMERR_DISSOLVEFACES_FAILED,  | 
					
						
							|  |  |  | 			                "Could not create merged face"); | 
					
						
							|  |  |  | 			goto cleanup; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-09 09:52:32 +00:00
										 |  |  | 		/*if making the new face failed (e.g. overlapping test)
 | 
					
						
							|  |  |  | 		  unmark the original faces for deletion.*/ | 
					
						
							|  |  |  | 		BMO_ClearFlag(bm, f, FACE_ORIG); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 		BMO_SetFlag(bm, f, FACE_NEW); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		fcopied = 0; | 
					
						
							|  |  |  | 		l=BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f); | 
					
						
							|  |  |  | 		for (; l; l=BMIter_Step(&liter)) { | 
					
						
							|  |  |  | 			/*ensure winding is identical*/ | 
					
						
							|  |  |  | 			l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_LOOP, l); | 
					
						
							|  |  |  | 			for (; l2; l2=BMIter_Step(&liter2)) { | 
					
						
							|  |  |  | 				if (BMO_TestFlag(bm, l2->f, FACE_ORIG)) { | 
					
						
							|  |  |  | 					if (l2->v != l->v) | 
					
						
							|  |  |  | 						bmesh_loop_reverse(bm, l2->f); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			/*copy over attributes*/ | 
					
						
							|  |  |  | 			l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_LOOP, l); | 
					
						
							|  |  |  | 			for (; l2; l2=BMIter_Step(&liter2)) { | 
					
						
							|  |  |  | 				if (BMO_TestFlag(bm, l2->f, FACE_ORIG)) { | 
					
						
							|  |  |  | 					if (!fcopied) { | 
					
						
							|  |  |  | 						BM_Copy_Attributes(bm, bm, l2->f, f); | 
					
						
							|  |  |  | 						fcopied = 1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					BM_Copy_Attributes(bm, bm, l2, l); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	BMO_CallOpf(bm, "del geom=%ff context=%d", FACE_ORIG, DEL_FACES); | 
					
						
							| 
									
										
										
										
											2009-03-09 15:15:17 +00:00
										 |  |  | 	if (BMO_HasError(bm)) goto cleanup; | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 	BMO_Flag_To_Slot(bm, op, "regionout", FACE_NEW, BM_FACE); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | cleanup: | 
					
						
							|  |  |  | 	/*free/cleanup*/ | 
					
						
							|  |  |  | 	for (i=0; i<V_COUNT(regions); i++) { | 
					
						
							|  |  |  | 		if (regions[i]) V_FREE(regions[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	V_FREE(regions); | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-18 04:39:33 +00:00
										 |  |  | void dissolveedges_exec(BMesh *bm, BMOperator *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BMOperator fop; | 
					
						
							|  |  |  | 	BMOIter oiter; | 
					
						
							|  |  |  | 	BMIter iter; | 
					
						
							|  |  |  | 	BMVert *v, **verts = NULL; | 
					
						
							|  |  |  | 	V_DECLARE(verts); | 
					
						
							|  |  |  | 	BMEdge *e; | 
					
						
							|  |  |  | 	BMFace *f; | 
					
						
							|  |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BMO_ITER(e, &oiter, bm, op, "edges") { | 
					
						
							|  |  |  | 		if (BM_Edge_FaceCount(e) == 2) { | 
					
						
							|  |  |  | 			BMO_SetFlag(bm, e->v1, VERT_MARK); | 
					
						
							|  |  |  | 			BMO_SetFlag(bm, e->v2, VERT_MARK); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BM_Join_Faces(bm, e->loop->f,  | 
					
						
							|  |  |  | 				      ((BMLoop*)e->loop->radial.next->data)->f, | 
					
						
							|  |  |  | 				      e); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) { | 
					
						
							|  |  |  | 		if (BMO_TestFlag(bm, v, VERT_MARK) &&  | 
					
						
							|  |  |  | 			BM_Vert_EdgeCount(v) == 2)  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			V_GROW(verts); | 
					
						
							|  |  |  | 			verts[V_COUNT(verts)-1] = v; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i=0; i<V_COUNT(verts); i++) { | 
					
						
							|  |  |  | 		BM_Collapse_Vert(bm, verts[i]->edge, verts[i], 1.0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	V_FREE(verts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//BMO_InitOpf(bm, &fop, "dissolvefaces faces=%ff", FACE_MARK);
 | 
					
						
							|  |  |  | 	//BMO_Exec_Op(bm, &fop);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//BMO_CopySlot(op, &fop, "regionout", "regionout");
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//BMO_Finish_Op(bm, &fop);
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | static int test_extra_verts(BMesh *bm, BMVert *v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BMIter iter, liter, iter2, iter3; | 
					
						
							|  |  |  | 	BMFace *f, *f2; | 
					
						
							|  |  |  | 	BMLoop *l; | 
					
						
							|  |  |  | 	BMEdge *e; | 
					
						
							|  |  |  | 	int found; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*test faces around verts for verts that would be wronly killed
 | 
					
						
							|  |  |  | 	  by dissolve faces.*/ | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 	f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v); | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 	for (; f; f=BMIter_Step(&iter)) { | 
					
						
							|  |  |  | 		l=BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f); | 
					
						
							|  |  |  | 		for (; l; l=BMIter_Step(&liter)) { | 
					
						
							|  |  |  | 			if (!BMO_TestFlag(bm, l->v, VERT_MARK)) { | 
					
						
							|  |  |  | 				/*if an edge around a vert is a boundary edge,
 | 
					
						
							|  |  |  | 				   then dissolve faces won't destroy it. | 
					
						
							|  |  |  | 				   also if it forms a boundary with one | 
					
						
							|  |  |  | 				   of the face regions*/ | 
					
						
							|  |  |  | 				found = 0; | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 				e = BMIter_New(&iter2, bm, BM_EDGES_OF_VERT, l->v); | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 				for (; e; e=BMIter_Step(&iter2)) { | 
					
						
							| 
									
										
										
										
											2009-03-14 02:52:16 +00:00
										 |  |  | 					if (BM_Edge_FaceCount(e)==1) found = 1; | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 					f2 = BMIter_New(&iter3, bm, BM_FACES_OF_EDGE, e); | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 					for (; f2; f2=BMIter_Step(&iter3)) { | 
					
						
							|  |  |  | 						if (!BMO_TestFlag(bm, f2, FACE_MARK)) { | 
					
						
							|  |  |  | 							found = 1; | 
					
						
							|  |  |  | 							break; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if (found) break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (!found) return 0; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-15 01:02:51 +00:00
										 |  |  | void dissolveverts_exec(BMesh *bm, BMOperator *op) | 
					
						
							| 
									
										
										
										
											2009-01-21 10:11:01 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	BMOpSlot *vinput; | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	BMIter iter, fiter; | 
					
						
							| 
									
										
										
										
											2009-02-15 01:02:51 +00:00
										 |  |  | 	BMVert *v; | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	BMFace *f; | 
					
						
							| 
									
										
										
										
											2009-03-09 15:15:17 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2009-01-21 10:11:01 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 	vinput = BMO_GetSlot(op, "verts"); | 
					
						
							|  |  |  | 	BMO_Flag_Buffer(bm, op, "verts", VERT_MARK); | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 	for (v=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v=BMIter_Step(&iter)) { | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 		if (BMO_TestFlag(bm, v, VERT_MARK)) { | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 			f=BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 			for (; f; f=BMIter_Step(&fiter)) { | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 				BMO_SetFlag(bm, f, FACE_ORIG); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 				BMO_SetFlag(bm, f, FACE_MARK); | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			/*check if our additions to the input to face dissolve
 | 
					
						
							|  |  |  | 			  will destroy nonmarked vertices.*/ | 
					
						
							|  |  |  | 			if (!test_extra_verts(bm, v)) { | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 				f=BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v); | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 				for (; f; f=BMIter_Step(&fiter)) { | 
					
						
							|  |  |  | 					if (BMO_TestFlag(bm, f, FACE_ORIG)) { | 
					
						
							|  |  |  | 						BMO_ClearFlag(bm, f, FACE_MARK); | 
					
						
							|  |  |  | 						BMO_ClearFlag(bm, f, FACE_ORIG); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 				f=BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v); | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 				for (; f; f=BMIter_Step(&fiter)) { | 
					
						
							|  |  |  | 					BMO_ClearFlag(bm, f, FACE_ORIG); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2009-01-21 10:11:01 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-01-21 10:11:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	BMO_CallOpf(bm, "dissolvefaces faces=%ff", FACE_MARK); | 
					
						
							|  |  |  | 	if (BMO_HasError(bm)) { | 
					
						
							| 
									
										
										
										
											2009-03-09 09:52:32 +00:00
										 |  |  | 			char *msg; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BMO_GetError(bm, &msg, NULL); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 			BMO_ClearStack(bm); | 
					
						
							| 
									
										
										
										
											2009-03-09 09:52:32 +00:00
										 |  |  | 			BMO_RaiseError(bm, op, BMERR_DISSOLVEVERTS_FAILED,msg); | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-03-09 15:15:17 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/*clean up any remaining*/ | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 	for (v=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); v; v=BMIter_Step(&iter)) { | 
					
						
							| 
									
										
										
										
											2009-03-09 15:15:17 +00:00
										 |  |  | 		if (BMO_TestFlag(bm, v, VERT_MARK)) { | 
					
						
							|  |  |  | 			if (!BM_Dissolve_Vert(bm, v)) { | 
					
						
							|  |  |  | 				BMO_RaiseError(bm, op,  | 
					
						
							|  |  |  | 					BMERR_DISSOLVEVERTS_FAILED, NULL); | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | /*this code is for cleaning up two-edged faces, it shall become
 | 
					
						
							|  |  |  |   it's own function one day.*/ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 		/*clean up two-edged faces*/ | 
					
						
							|  |  |  | 		/*basic idea is to keep joining 2-edged faces until their
 | 
					
						
							|  |  |  | 		  gone.  this however relies on joining two 2-edged faces | 
					
						
							|  |  |  | 		  together to work, which doesn't.*/ | 
					
						
							|  |  |  | 		found3 = 1; | 
					
						
							|  |  |  | 		while (found3) { | 
					
						
							|  |  |  | 			found3 = 0; | 
					
						
							| 
									
										
										
										
											2009-03-22 23:16:43 +00:00
										 |  |  | 			for (f=BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL); f; f=BMIter_Step(&iter)){ | 
					
						
							| 
									
										
										
										
											2009-03-02 02:21:18 +00:00
										 |  |  | 				if (!BM_Validate_Face(bm, f, stderr)) { | 
					
						
							| 
									
										
										
										
											2009-02-28 12:49:18 +00:00
										 |  |  | 					printf("error.\n"); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 				if (f->len == 2) { | 
					
						
							|  |  |  | 					//this design relies on join faces working
 | 
					
						
							|  |  |  | 					//with two-edged faces properly.
 | 
					
						
							|  |  |  | 					//commenting this line disables the
 | 
					
						
							|  |  |  | 					//outermost loop.
 | 
					
						
							|  |  |  | 					//found3 = 1;
 | 
					
						
							|  |  |  | 					found2 = 0; | 
					
						
							|  |  |  | 					l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f); | 
					
						
							|  |  |  | 					fe = l->e; | 
					
						
							|  |  |  | 					for (; l; l=BMIter_Step(&liter)) { | 
					
						
							|  |  |  | 						f2 = BMIter_New(&fiter, bm, | 
					
						
							| 
									
										
										
										
											2009-05-16 16:18:08 +00:00
										 |  |  | 								BM_FACES_OF_EDGE, l->e); | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 						for (; f2; f2=BMIter_Step(&fiter)) { | 
					
						
							|  |  |  | 							if (f2 != f) { | 
					
						
							| 
									
										
										
										
											2009-03-13 13:11:50 +00:00
										 |  |  | 								BM_Join_Faces(bm, f, f2, l->e); | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 								found2 = 1; | 
					
						
							|  |  |  | 								break; | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						if (found2) break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					if (!found2) { | 
					
						
							|  |  |  | 						bmesh_kf(bm, f); | 
					
						
							|  |  |  | 						bmesh_ke(bm, fe); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-02-15 14:02:27 +00:00
										 |  |  | 				} /*else if (f->len == 3) {
 | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 					BMEdge *ed[3]; | 
					
						
							|  |  |  | 					BMVert *vt[3]; | 
					
						
							|  |  |  | 					BMLoop *lp[3]; | 
					
						
							|  |  |  | 					int i=0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-15 14:02:27 +00:00
										 |  |  | 					//check for duplicate edges
 | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 					l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f); | 
					
						
							|  |  |  | 					for (; l; l=BMIter_Step(&liter)) { | 
					
						
							| 
									
										
										
										
											2009-02-15 14:02:27 +00:00
										 |  |  | 						ed[i] = l->e;	 | 
					
						
							|  |  |  | 						lp[i] = l; | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 						vt[i++] = l->v; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if (vt[0] == vt[1] || vt[0] == vt[2]) { | 
					
						
							|  |  |  | 						i += 1; | 
					
						
							| 
									
										
										
										
											2009-02-15 01:02:51 +00:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2009-02-15 14:02:27 +00:00
										 |  |  | 				}*/ | 
					
						
							| 
									
										
										
										
											2009-02-15 01:02:51 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2009-02-15 02:14:40 +00:00
										 |  |  | 		if (oldlen == len) break; | 
					
						
							|  |  |  | 		oldlen = len; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-08 15:02:49 +00:00
										 |  |  | #endif
 |