| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Joseph Eagar. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-08 23:43:11 +00:00
										 |  |  | /** \file blender/bmesh/operators/bmo_triangulate.c
 | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  |  *  \ingroup bmesh | 
					
						
							| 
									
										
										
										
											2013-03-30 08:54:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Triangulate faces, also defines triangle fill. | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 06:48:57 +00:00
										 |  |  | #include "DNA_listBase.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | #include "BLI_sort_utils.h"
 | 
					
						
							| 
									
										
										
										
											2012-04-16 06:48:57 +00:00
										 |  |  | #include "BLI_scanfill.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "bmesh.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-23 04:22:07 +00:00
										 |  |  | #include "bmesh_tools.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-25 22:40:11 +00:00
										 |  |  | #include "intern/bmesh_operators_private.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define ELE_NEW		1
 | 
					
						
							|  |  |  | #define EDGE_MARK	4
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-28 09:48:00 +00:00
										 |  |  | void bmo_triangulate_exec(BMesh *bm, BMOperator *op) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-10-29 02:42:51 +00:00
										 |  |  | 	const int quad_method = BMO_slot_int_get(op->slots_in, "quad_method"); | 
					
						
							|  |  |  | 	const int ngon_method = BMO_slot_int_get(op->slots_in, "ngon_method"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-05 11:30:50 +00:00
										 |  |  | 	BMOpSlot *slot_facemap_out = BMO_slot_get(op->slots_out, "face_map.out"); | 
					
						
							| 
									
										
										
										
											2015-11-06 01:05:38 +11:00
										 |  |  | 	BMOpSlot *slot_facemap_double_out = BMO_slot_get(op->slots_out, "face_map_double.out"); | 
					
						
							| 
									
										
										
										
											2012-04-23 02:17:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-29 10:31:05 +00:00
										 |  |  | 	BM_mesh_elem_hflag_disable_all(bm, BM_FACE | BM_EDGE, BM_ELEM_TAG, false); | 
					
						
							|  |  |  | 	BMO_slot_buffer_hflag_enable(bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-06 01:05:38 +11:00
										 |  |  | 	BM_mesh_triangulate(bm, quad_method, ngon_method, true, op, slot_facemap_out, slot_facemap_double_out); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-29 10:31:05 +00:00
										 |  |  | 	BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); | 
					
						
							|  |  |  | 	BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); | 
					
						
							| 
									
										
										
										
											2015-11-06 01:05:38 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | struct SortNormal { | 
					
						
							|  |  |  | 	float value;  /* keep first */ | 
					
						
							|  |  |  | 	float no[3]; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-28 09:48:00 +00:00
										 |  |  | void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-02-09 15:49:20 +00:00
										 |  |  | 	const bool use_beauty = BMO_slot_bool_get(op->slots_in, "use_beauty"); | 
					
						
							| 
									
										
										
										
											2013-08-23 11:10:46 +00:00
										 |  |  | 	const bool use_dissolve = BMO_slot_bool_get(op->slots_in, "use_dissolve"); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	BMOIter siter; | 
					
						
							|  |  |  | 	BMEdge *e; | 
					
						
							| 
									
										
										
										
											2012-04-16 06:48:57 +00:00
										 |  |  | 	ScanFillContext sf_ctx; | 
					
						
							| 
									
										
										
										
											2012-05-13 14:47:53 +00:00
										 |  |  | 	/* ScanFillEdge *sf_edge; */ /* UNUSED */ | 
					
						
							|  |  |  | 	ScanFillFace *sf_tri; | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 	GHash *sf_vert_map; | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | 	float normal[3]; | 
					
						
							| 
									
										
										
										
											2014-02-13 19:09:28 +11:00
										 |  |  | 	const int scanfill_flag = BLI_SCANFILL_CALC_HOLES | BLI_SCANFILL_CALC_POLYS | BLI_SCANFILL_CALC_LOOSE; | 
					
						
							| 
									
										
										
										
											2014-11-04 09:48:41 +01:00
										 |  |  | 	unsigned int nors_tot; | 
					
						
							| 
									
										
										
										
											2014-08-21 12:18:55 +10:00
										 |  |  | 	bool calc_winding = false; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 	sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_count(op->slots_in, "edges")); | 
					
						
							| 
									
										
										
										
											2013-08-23 10:12:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BMO_slot_vec_get(op->slots_in, "normal", normal); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-05 00:23:55 +00:00
										 |  |  | 	BLI_scanfill_begin(&sf_ctx); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-11-19 14:58:31 +00:00
										 |  |  | 	BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 		ScanFillVert *sf_verts[2]; | 
					
						
							|  |  |  | 		BMVert **e_verts = &e->v1; | 
					
						
							|  |  |  | 		unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 		BMO_edge_flag_enable(bm, e, EDGE_MARK); | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 12:18:55 +10:00
										 |  |  | 		calc_winding = (calc_winding || BM_edge_is_boundary(e)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 		for (i = 0; i < 2; i++) { | 
					
						
							|  |  |  | 			if ((sf_verts[i] = BLI_ghash_lookup(sf_vert_map, e_verts[i])) == NULL) { | 
					
						
							|  |  |  | 				sf_verts[i] = BLI_scanfill_vert_add(&sf_ctx, e_verts[i]->co); | 
					
						
							|  |  |  | 				sf_verts[i]->tmp.p = e_verts[i]; | 
					
						
							|  |  |  | 				BLI_ghash_insert(sf_vert_map, e_verts[i], sf_verts[i]); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-02 17:09:38 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 		/* sf_edge = */ BLI_scanfill_edge_add(&sf_ctx, UNPACK2(sf_verts)); | 
					
						
							| 
									
										
										
										
											2012-05-13 14:47:53 +00:00
										 |  |  | 		/* sf_edge->tmp.p = e; */ /* UNUSED */ | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-11-04 09:48:41 +01:00
										 |  |  | 	nors_tot = BLI_ghash_size(sf_vert_map); | 
					
						
							| 
									
										
										
										
											2014-08-21 11:47:10 +10:00
										 |  |  | 	BLI_ghash_free(sf_vert_map, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-23 10:12:09 +00:00
										 |  |  | 	if (is_zero_v3(normal)) { | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | 		/* calculate the normal from the cross product of vert-edge pairs.
 | 
					
						
							|  |  |  | 		 * Since we don't know winding, just accumulate */ | 
					
						
							|  |  |  | 		ScanFillVert *sf_vert; | 
					
						
							|  |  |  | 		struct SortNormal *nors; | 
					
						
							|  |  |  | 		unsigned int i; | 
					
						
							|  |  |  | 		bool is_degenerate = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		nors = MEM_mallocN(sizeof(*nors) * nors_tot, __func__); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (sf_vert = sf_ctx.fillvertbase.first, i = 0; sf_vert; sf_vert = sf_vert->next, i++) { | 
					
						
							|  |  |  | 			BMVert *v = sf_vert->tmp.p; | 
					
						
							|  |  |  | 			BMIter eiter; | 
					
						
							| 
									
										
										
										
											2015-11-23 12:34:50 +11:00
										 |  |  | 			BMEdge *e_pair[2]; | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | 			unsigned int e_index = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			nors[i].value = -1.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* only use if 'is_degenerate' stays true */ | 
					
						
							|  |  |  | 			add_v3_v3(normal, v->no); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 				if (BMO_edge_flag_test(bm, e, EDGE_MARK)) { | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | 					if (e_index == 2) { | 
					
						
							|  |  |  | 						e_index = 0; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					e_pair[e_index++] = e; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (e_index == 2) { | 
					
						
							|  |  |  | 				float dir_a[3], dir_b[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				is_degenerate = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				sub_v3_v3v3(dir_a, v->co, BM_edge_other_vert(e_pair[0], v)->co); | 
					
						
							|  |  |  | 				sub_v3_v3v3(dir_b, v->co, BM_edge_other_vert(e_pair[1], v)->co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				cross_v3_v3v3(nors[i].no, dir_a, dir_b); | 
					
						
							|  |  |  | 				nors[i].value = len_squared_v3(nors[i].no); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* only to get deterministic behavior (for initial normal) */ | 
					
						
							|  |  |  | 				if (len_squared_v3(dir_a) > len_squared_v3(dir_b)) { | 
					
						
							|  |  |  | 					negate_v3(nors[i].no); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (UNLIKELY(is_degenerate)) { | 
					
						
							|  |  |  | 			/* no vertices have 2 edges?
 | 
					
						
							|  |  |  | 			 * in this case fall back to the average vertex normals */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			qsort(nors, nors_tot, sizeof(*nors), BLI_sortutil_cmp_float_reverse); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			copy_v3_v3(normal, nors[0].no); | 
					
						
							|  |  |  | 			for (i = 0; i < nors_tot; i++) { | 
					
						
							|  |  |  | 				if (UNLIKELY(nors[i].value == -1.0f)) { | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (dot_v3v3(normal, nors[i].no) < 0.0f) { | 
					
						
							|  |  |  | 					negate_v3(nors[i].no); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				add_v3_v3(normal, nors[i].no); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			normalize_v3(normal); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		MEM_freeN(nors); | 
					
						
							| 
									
										
										
										
											2013-08-23 10:12:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2014-08-21 12:18:55 +10:00
										 |  |  | 		calc_winding = false; | 
					
						
							| 
									
										
										
										
											2013-08-23 10:12:09 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-05 14:19:14 +01:00
										 |  |  | 	/* in this case we almost certainly have degenerate geometry,
 | 
					
						
							|  |  |  | 	 * better set a fallback value as a last resort */ | 
					
						
							|  |  |  | 	if (UNLIKELY(normalize_v3(normal) == 0.0f)) { | 
					
						
							|  |  |  | 		normal[2] = 1.0f; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-08-21 15:07:07 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BLI_scanfill_calc_ex(&sf_ctx, scanfill_flag, normal); | 
					
						
							| 
									
										
										
										
											2014-08-21 12:18:55 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* if we have existing faces, base winding on those */ | 
					
						
							|  |  |  | 	if (calc_winding) { | 
					
						
							|  |  |  | 		int winding_votes = 0; | 
					
						
							|  |  |  | 		for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { | 
					
						
							|  |  |  | 			BMVert *v_tri[3] = {sf_tri->v1->tmp.p, sf_tri->v2->tmp.p, sf_tri->v3->tmp.p}; | 
					
						
							|  |  |  | 			unsigned int i, i_prev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (i = 0, i_prev = 2; i < 3; i_prev = i++) { | 
					
						
							|  |  |  | 				e = BM_edge_exists(v_tri[i], v_tri[i_prev]); | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 				if (e && BM_edge_is_boundary(e) && BMO_edge_flag_test(bm, e, EDGE_MARK)) { | 
					
						
							| 
									
										
										
										
											2014-08-21 12:18:55 +10:00
										 |  |  | 					winding_votes += (e->l->v == v_tri[i]) ? 1 : -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (winding_votes < 0) { | 
					
						
							|  |  |  | 			for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { | 
					
						
							|  |  |  | 				SWAP(struct ScanFillVert *, sf_tri->v2, sf_tri->v3); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-13 14:47:53 +00:00
										 |  |  | 	for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { | 
					
						
							| 
									
										
										
										
											2014-08-21 12:57:03 +10:00
										 |  |  | 		BMFace *f; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		BMLoop *l; | 
					
						
							|  |  |  | 		BMIter liter; | 
					
						
							| 
									
										
										
										
											2014-08-21 12:57:03 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		f = BM_face_create_quad_tri(bm, | 
					
						
							|  |  |  | 		                            sf_tri->v1->tmp.p, sf_tri->v2->tmp.p, sf_tri->v3->tmp.p, NULL, | 
					
						
							|  |  |  | 		                            NULL, BM_CREATE_NO_DOUBLE); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		 | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 		BMO_face_flag_enable(bm, f, ELE_NEW); | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 		BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 			if (!BMO_edge_flag_test(bm, l->e, EDGE_MARK)) { | 
					
						
							|  |  |  | 				BMO_edge_flag_enable(bm, l->e, ELE_NEW); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-05 00:23:55 +00:00
										 |  |  | 	BLI_scanfill_end(&sf_ctx); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2013-02-09 15:49:20 +00:00
										 |  |  | 	if (use_beauty) { | 
					
						
							|  |  |  | 		BMOperator bmop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BMO_op_initf(bm, &bmop, op->flag, "beautify_fill faces=%ff edges=%Fe", ELE_NEW, EDGE_MARK); | 
					
						
							|  |  |  | 		BMO_op_exec(bm, &bmop); | 
					
						
							|  |  |  | 		BMO_slot_buffer_flag_enable(bm, bmop.slots_out, "geom.out", BM_FACE | BM_EDGE, ELE_NEW); | 
					
						
							|  |  |  | 		BMO_op_finish(bm, &bmop); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-08-23 11:10:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (use_dissolve) { | 
					
						
							| 
									
										
										
										
											2016-06-17 21:45:56 +10:00
										 |  |  | 		BMEdge *e_next; | 
					
						
							|  |  |  | 		BMIter iter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 			if (BMO_edge_flag_test(bm, e, ELE_NEW)) { | 
					
						
							| 
									
										
										
										
											2016-06-17 21:45:56 +10:00
										 |  |  | 				/* in rare cases the edges face will have already been removed from the edge */ | 
					
						
							|  |  |  | 				if (LIKELY(e->l)) { | 
					
						
							|  |  |  | 					BMFace *f_new = BM_faces_join_pair( | 
					
						
							|  |  |  | 					        bm, e->l->f, | 
					
						
							|  |  |  | 					        e->l->radial_next->f, e, | 
					
						
							|  |  |  | 					        false); /* join faces */ | 
					
						
							|  |  |  | 					if (f_new) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 						BMO_face_flag_enable(bm, f_new, ELE_NEW); | 
					
						
							| 
									
										
										
										
											2016-06-17 21:45:56 +10:00
										 |  |  | 						BM_edge_kill(bm, e); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						BMO_error_clear(bm); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2013-08-23 11:28:33 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							| 
									
										
										
										
											2016-06-17 21:45:56 +10:00
										 |  |  | 					BM_edge_kill(bm, e); | 
					
						
							| 
									
										
										
										
											2013-08-23 11:28:33 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-08-23 11:10:46 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-17 21:45:56 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_EDGE | BM_FACE, ELE_NEW); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } |