| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup bmesh | 
					
						
							| 
									
										
										
										
											2013-03-30 08:54:50 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Convert triangle to quads. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * TODO | 
					
						
							|  |  |  |  * - convert triangles to any sided faces, not just quads. | 
					
						
							| 
									
										
										
										
											2012-04-06 09:21:19 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2013-09-05 22:24:12 +00:00
										 |  |  | #include "BLI_sort_utils.h"
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-05 17:56:54 +00:00
										 |  |  | #include "BKE_customdata.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | #include "bmesh.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-08 03:25:53 +00:00
										 |  |  | #include "intern/bmesh_operators_private.h" /* own include */
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* assumes edges are validated before reaching this poin */ | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | static float quad_calc_error( | 
					
						
							| 
									
										
										
										
											2015-05-05 15:59:26 +10:00
										 |  |  |         const float v1[3], const float v2[3], | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  |         const float v3[3], const float v4[3]) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-11 19:09:01 +00:00
										 |  |  | 	/* gives a 'weight' to a pair of triangles that join an edge to decide how good a join they would make */ | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	/* Note: this is more complicated than it needs to be and should be cleaned up.. */ | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	float error = 0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Normal difference */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		float n1[3], n2[3]; | 
					
						
							|  |  |  | 		float angle_a, angle_b; | 
					
						
							|  |  |  | 		float diff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		normal_tri_v3(n1, v1, v2, v3); | 
					
						
							|  |  |  | 		normal_tri_v3(n2, v1, v3, v4); | 
					
						
							|  |  |  | 		angle_a = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : angle_normalized_v3v3(n1, n2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		normal_tri_v3(n1, v2, v3, v4); | 
					
						
							|  |  |  | 		normal_tri_v3(n2, v4, v1, v2); | 
					
						
							|  |  |  | 		angle_b = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : angle_normalized_v3v3(n1, n2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		diff = (angle_a + angle_b) / (float)(M_PI * 2); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		error += diff; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	/* Colinearity */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		float edge_vecs[4][3]; | 
					
						
							|  |  |  | 		float diff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		sub_v3_v3v3(edge_vecs[0], v1, v2); | 
					
						
							|  |  |  | 		sub_v3_v3v3(edge_vecs[1], v2, v3); | 
					
						
							|  |  |  | 		sub_v3_v3v3(edge_vecs[2], v3, v4); | 
					
						
							|  |  |  | 		sub_v3_v3v3(edge_vecs[3], v4, v1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		normalize_v3(edge_vecs[0]); | 
					
						
							|  |  |  | 		normalize_v3(edge_vecs[1]); | 
					
						
							|  |  |  | 		normalize_v3(edge_vecs[2]); | 
					
						
							|  |  |  | 		normalize_v3(edge_vecs[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* a completely skinny face is 'pi' after halving */ | 
					
						
							|  |  |  | 		diff = (fabsf(angle_normalized_v3v3(edge_vecs[0], edge_vecs[1]) - (float)M_PI_2) + | 
					
						
							|  |  |  | 		        fabsf(angle_normalized_v3v3(edge_vecs[1], edge_vecs[2]) - (float)M_PI_2) + | 
					
						
							|  |  |  | 		        fabsf(angle_normalized_v3v3(edge_vecs[2], edge_vecs[3]) - (float)M_PI_2) + | 
					
						
							|  |  |  | 		        fabsf(angle_normalized_v3v3(edge_vecs[3], edge_vecs[0]) - (float)M_PI_2)) / (float)(M_PI * 2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		error += diff; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	/* Concavity */ | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		float area_min, area_max, area_a, area_b; | 
					
						
							|  |  |  | 		float diff; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		area_a = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v3, v4); | 
					
						
							|  |  |  | 		area_b = area_tri_v3(v2, v3, v4) + area_tri_v3(v4, v1, v2); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		area_min = min_ff(area_a, area_b); | 
					
						
							|  |  |  | 		area_max = max_ff(area_a, area_b); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-25 13:26:20 +10:00
										 |  |  | 		diff = area_max ? (1.0f - (area_min / area_max)) : 1.0f; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		error += diff; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return error; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | static void bm_edge_to_quad_verts(const BMEdge *e, const BMVert *r_v_quad[4]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BLI_assert(e->l->f->len == 3 && e->l->radial_next->f->len == 3); | 
					
						
							|  |  |  | 	BLI_assert(BM_edge_is_manifold(e)); | 
					
						
							|  |  |  | 	r_v_quad[0] = e->l->v; | 
					
						
							|  |  |  | 	r_v_quad[1] = e->l->prev->v; | 
					
						
							|  |  |  | 	r_v_quad[2] = e->l->next->v; | 
					
						
							|  |  |  | 	r_v_quad[3] = e->l->radial_next->prev->v; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | /* cache customdata delimiters */ | 
					
						
							|  |  |  | struct DelimitData_CD { | 
					
						
							|  |  |  | 	int cd_type; | 
					
						
							|  |  |  | 	int cd_size; | 
					
						
							|  |  |  | 	int cd_offset; | 
					
						
							|  |  |  | 	int cd_offset_end; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct DelimitData { | 
					
						
							| 
									
										
										
										
											2017-05-06 14:18:31 +10:00
										 |  |  | 	uint do_seam : 1; | 
					
						
							|  |  |  | 	uint do_sharp : 1; | 
					
						
							|  |  |  | 	uint do_mat : 1; | 
					
						
							|  |  |  | 	uint do_angle_face : 1; | 
					
						
							|  |  |  | 	uint do_angle_shape : 1; | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 14:27:38 +10:00
										 |  |  | 	float angle_face; | 
					
						
							|  |  |  | 	float angle_face__cos; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	float angle_shape; | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	struct DelimitData_CD cdata[4]; | 
					
						
							|  |  |  | 	int cdata_len; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool bm_edge_is_contiguous_loop_cd_all( | 
					
						
							|  |  |  |         const BMEdge *e, const struct DelimitData_CD *delimit_data) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	int cd_offset; | 
					
						
							|  |  |  | 	for (cd_offset = delimit_data->cd_offset; | 
					
						
							|  |  |  | 	     cd_offset < delimit_data->cd_offset_end; | 
					
						
							|  |  |  | 	     cd_offset += delimit_data->cd_size) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (BM_edge_is_contiguous_loop_cd(e, delimit_data->cd_type, cd_offset) == false) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static bool bm_edge_delimit_cdata( | 
					
						
							|  |  |  |         CustomData *ldata, CustomDataType type, | 
					
						
							|  |  |  |         struct DelimitData_CD *r_delim_cd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	const int layer_len = CustomData_number_of_layers(ldata, type); | 
					
						
							|  |  |  | 	r_delim_cd->cd_type = type; | 
					
						
							|  |  |  | 	r_delim_cd->cd_size = CustomData_sizeof(r_delim_cd->cd_type); | 
					
						
							|  |  |  | 	r_delim_cd->cd_offset = CustomData_get_n_offset(ldata, type, 0); | 
					
						
							|  |  |  | 	r_delim_cd->cd_offset_end = r_delim_cd->cd_size * layer_len; | 
					
						
							|  |  |  | 	return (r_delim_cd->cd_offset != -1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static float bm_edge_is_delimit( | 
					
						
							|  |  |  |         const BMEdge *e, | 
					
						
							|  |  |  |         const struct DelimitData *delimit_data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	BMFace *f_a = e->l->f, *f_b = e->l->radial_next->f; | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	const bool is_contig = BM_edge_is_contiguous(e); | 
					
						
							|  |  |  | 	float angle; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((delimit_data->do_seam) && | 
					
						
							|  |  |  | 	    (BM_elem_flag_test(e, BM_ELEM_SEAM))) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	if ((delimit_data->do_sharp) && | 
					
						
							|  |  |  | 	    (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == 0)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							| 
									
										
										
										
											2012-09-19 04:48:34 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	if ((delimit_data->do_mat) && | 
					
						
							|  |  |  | 	    (f_a->mat_nr != f_b->mat_nr)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 14:27:38 +10:00
										 |  |  | 	if (delimit_data->do_angle_face) { | 
					
						
							|  |  |  | 		if (dot_v3v3(f_a->no, f_b->no) < delimit_data->angle_face__cos) { | 
					
						
							|  |  |  | 			goto fail; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (delimit_data->do_angle_shape) { | 
					
						
							|  |  |  | 		const BMVert *verts[4]; | 
					
						
							|  |  |  | 		bm_edge_to_quad_verts(e, verts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* if we're checking the shape at all, a flipped face is out of the question */ | 
					
						
							|  |  |  | 		if (is_quad_flip_v3(verts[0]->co, verts[1]->co, verts[2]->co, verts[3]->co)) { | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 			goto fail; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			float edge_vecs[4][3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			sub_v3_v3v3(edge_vecs[0], verts[0]->co, verts[1]->co); | 
					
						
							|  |  |  | 			sub_v3_v3v3(edge_vecs[1], verts[1]->co, verts[2]->co); | 
					
						
							|  |  |  | 			sub_v3_v3v3(edge_vecs[2], verts[2]->co, verts[3]->co); | 
					
						
							|  |  |  | 			sub_v3_v3v3(edge_vecs[3], verts[3]->co, verts[0]->co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			normalize_v3(edge_vecs[0]); | 
					
						
							|  |  |  | 			normalize_v3(edge_vecs[1]); | 
					
						
							|  |  |  | 			normalize_v3(edge_vecs[2]); | 
					
						
							|  |  |  | 			normalize_v3(edge_vecs[3]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 14:27:38 +10:00
										 |  |  | 			if ((fabsf(angle_normalized_v3v3(edge_vecs[0], edge_vecs[1]) - (float)M_PI_2) > delimit_data->angle_shape) || | 
					
						
							|  |  |  | 			    (fabsf(angle_normalized_v3v3(edge_vecs[1], edge_vecs[2]) - (float)M_PI_2) > delimit_data->angle_shape) || | 
					
						
							|  |  |  | 			    (fabsf(angle_normalized_v3v3(edge_vecs[2], edge_vecs[3]) - (float)M_PI_2) > delimit_data->angle_shape) || | 
					
						
							|  |  |  | 			    (fabsf(angle_normalized_v3v3(edge_vecs[3], edge_vecs[0]) - (float)M_PI_2) > delimit_data->angle_shape)) | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 			{ | 
					
						
							|  |  |  | 				goto fail; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	if (delimit_data->cdata_len) { | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		for (i = 0; i < delimit_data->cdata_len; i++) { | 
					
						
							|  |  |  | 			if (!bm_edge_is_contiguous_loop_cd_all(e, &delimit_data->cdata[i])) { | 
					
						
							|  |  |  | 				goto fail; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | fail: | 
					
						
							| 
									
										
										
										
											2013-01-14 16:42:43 +00:00
										 |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | #define EDGE_MARK	(1 << 0)
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | #define FACE_OUT (1 << 0)
 | 
					
						
							|  |  |  | #define FACE_INPUT	(1 << 2)
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-28 09:48:00 +00:00
										 |  |  | void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-05-26 14:27:38 +10:00
										 |  |  | 	float angle_face, angle_shape; | 
					
						
							| 
									
										
										
										
											2013-01-14 16:42:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	BMIter iter; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	BMOIter siter; | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	BMFace *f; | 
					
						
							| 
									
										
										
										
											2015-06-20 16:48:59 +10:00
										 |  |  | 	BMEdge *e; | 
					
						
							| 
									
										
										
										
											2013-09-05 22:24:12 +00:00
										 |  |  | 	/* data: edge-to-join, sort_value: error weight */ | 
					
						
							| 
									
										
										
										
											2018-03-31 19:25:27 +02:00
										 |  |  | 	struct SortPtrByFloat *jedges; | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	unsigned i, totedge; | 
					
						
							| 
									
										
										
										
											2017-05-06 14:18:31 +10:00
										 |  |  | 	uint totedge_tag = 0; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	struct DelimitData delimit_data = {0}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	delimit_data.do_seam = BMO_slot_bool_get(op->slots_in, "cmp_seam"); | 
					
						
							|  |  |  | 	delimit_data.do_sharp = BMO_slot_bool_get(op->slots_in, "cmp_sharp"); | 
					
						
							|  |  |  | 	delimit_data.do_mat = BMO_slot_bool_get(op->slots_in, "cmp_materials"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 14:27:38 +10:00
										 |  |  | 	angle_face = BMO_slot_float_get(op->slots_in, "angle_face_threshold"); | 
					
						
							|  |  |  | 	if (angle_face < DEG2RADF(180.0f)) { | 
					
						
							|  |  |  | 		delimit_data.angle_face = angle_face; | 
					
						
							|  |  |  | 		delimit_data.angle_face__cos = cosf(angle_face); | 
					
						
							|  |  |  | 		delimit_data.do_angle_face = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		delimit_data.do_angle_face = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	angle_shape = BMO_slot_float_get(op->slots_in, "angle_shape_threshold"); | 
					
						
							|  |  |  | 	if (angle_shape < DEG2RADF(180.0f)) { | 
					
						
							|  |  |  | 		delimit_data.angle_shape = angle_shape; | 
					
						
							|  |  |  | 		delimit_data.do_angle_shape = true; | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2015-05-26 14:27:38 +10:00
										 |  |  | 		delimit_data.do_angle_shape = false; | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (BMO_slot_bool_get(op->slots_in, "cmp_uvs") && | 
					
						
							|  |  |  | 	    bm_edge_delimit_cdata(&bm->ldata, CD_MLOOPUV, &delimit_data.cdata[delimit_data.cdata_len])) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		delimit_data.cdata_len += 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	delimit_data.cdata[delimit_data.cdata_len].cd_offset = -1; | 
					
						
							|  |  |  | 	if (BMO_slot_bool_get(op->slots_in, "cmp_vcols") && | 
					
						
							|  |  |  | 	    bm_edge_delimit_cdata(&bm->ldata, CD_MLOOPCOL, &delimit_data.cdata[delimit_data.cdata_len])) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		delimit_data.cdata_len += 1; | 
					
						
							| 
									
										
										
										
											2015-05-22 18:12:54 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	/* flag all edges of all input face */ | 
					
						
							| 
									
										
										
										
											2012-11-19 14:58:31 +00:00
										 |  |  | 	BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { | 
					
						
							| 
									
										
										
										
											2013-08-02 13:35:04 +00:00
										 |  |  | 		if (f->len == 3) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 			BMO_face_flag_enable(bm, f, FACE_INPUT); | 
					
						
							| 
									
										
										
										
											2013-08-02 13:35:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	/* flag edges surrounded by 2 flagged triangles */ | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 		BMFace *f_a, *f_b; | 
					
						
							|  |  |  | 		if (BM_edge_face_pair(e, &f_a, &f_b) && | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 		    (BMO_face_flag_test(bm, f_a, FACE_INPUT) && | 
					
						
							|  |  |  | 		     BMO_face_flag_test(bm, f_b, FACE_INPUT))) | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 			if (!bm_edge_is_delimit(e, &delimit_data)) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 				BMO_edge_flag_enable(bm, e, EDGE_MARK); | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 				totedge_tag++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	if (totedge_tag == 0) { | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* over alloc, some of the edges will be delimited */ | 
					
						
							|  |  |  | 	jedges = MEM_mallocN(sizeof(*jedges) * totedge_tag, __func__); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	i = 0; | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 	BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		const BMVert *verts[4]; | 
					
						
							|  |  |  | 		float error; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-27 17:14:36 +11:00
										 |  |  | 		if (!BMO_edge_flag_test(bm, e, EDGE_MARK)) { | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2019-03-27 17:14:36 +11:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		bm_edge_to_quad_verts(e, verts); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		error = quad_calc_error(verts[0]->co, verts[1]->co, verts[2]->co, verts[3]->co); | 
					
						
							| 
									
										
										
										
											2012-09-19 04:48:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-26 13:39:07 +10:00
										 |  |  | 		jedges[i].data = e; | 
					
						
							|  |  |  | 		jedges[i].sort_value = error; | 
					
						
							|  |  |  | 		i++; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 	totedge = i; | 
					
						
							| 
									
										
										
										
											2013-09-05 22:24:12 +00:00
										 |  |  | 	qsort(jedges, totedge, sizeof(*jedges), BLI_sortutil_cmp_float); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < totedge; i++) { | 
					
						
							| 
									
										
										
										
											2016-11-12 10:06:53 +11:00
										 |  |  | 		BMLoop *l_a, *l_b; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-09-05 22:24:12 +00:00
										 |  |  | 		e = jedges[i].data; | 
					
						
							| 
									
										
										
										
											2016-11-12 10:06:53 +11:00
										 |  |  | 		l_a = e->l; | 
					
						
							|  |  |  | 		l_b = e->l->radial_next; | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 06:45:11 +00:00
										 |  |  | 		/* check if another edge already claimed this face */ | 
					
						
							| 
									
										
										
										
											2016-11-12 10:06:53 +11:00
										 |  |  | 		if ((l_a->f->len == 3) && (l_b->f->len == 3)) { | 
					
						
							| 
									
										
										
										
											2015-06-20 16:48:59 +10:00
										 |  |  | 			BMFace *f_new; | 
					
						
							| 
									
										
										
										
											2016-11-12 10:06:53 +11:00
										 |  |  | 			f_new = BM_faces_join_pair(bm, l_a, l_b, true); | 
					
						
							| 
									
										
										
										
											2013-08-02 13:35:04 +00:00
										 |  |  | 			if (f_new) { | 
					
						
							| 
									
										
										
										
											2016-07-01 19:07:11 +10:00
										 |  |  | 				BMO_face_flag_enable(bm, f_new, FACE_OUT); | 
					
						
							| 
									
										
										
										
											2013-08-02 13:35:04 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2013-07-27 06:11:54 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-20 16:48:59 +10:00
										 |  |  | 	MEM_freeN(jedges); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-07-27 06:11:54 +00:00
										 |  |  | 	BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_OUT); | 
					
						
							| 
									
										
										
										
											2012-02-19 18:31:04 +00:00
										 |  |  | } |