| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-10-23 17:52:20 +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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2005 by the Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Daniel Dunbar | 
					
						
							|  |  |  |  *                 Ton Roosendaal, | 
					
						
							|  |  |  |  *                 Ben Batt, | 
					
						
							|  |  |  |  *                 Brecht Van Lommel, | 
					
						
							|  |  |  |  *                 Campbell Barton | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 13:57:17 +00:00
										 |  |  | /** \file blender/modifiers/intern/MOD_edgesplit.c
 | 
					
						
							|  |  |  |  *  \ingroup modifiers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | /* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
 | 
					
						
							|  |  |  |  * or edge angle (can be used to achieve autosmoothing) */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 04:06:48 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-24 03:03:42 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:18:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #include "BKE_cdderivedmesh.h"
 | 
					
						
							|  |  |  | #include "BKE_modifier.h"
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | #include "BKE_tessmesh.h"
 | 
					
						
							| 
									
										
										
										
											2011-02-27 06:19:40 +00:00
										 |  |  | #include "BKE_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 04:19:44 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | /* EdgeSplit */ | 
					
						
							|  |  |  | /* EdgeSplit modifier: Splits edges in the mesh according to sharpness flag
 | 
					
						
							|  |  |  |  * or edge angle (can be used to achieve autosmoothing) | 
					
						
							| 
									
										
										
										
											2011-11-28 04:19:44 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * note: this code is very close to MOD_bevel.c | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | #define EDGE_MARK  1
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-11 19:58:56 +00:00
										 |  |  | static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Object *UNUSED(ob)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-12 15:02:33 +00:00
										 |  |  | 	DerivedMesh *result; | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	BMesh *bm; | 
					
						
							|  |  |  | 	BMEditMesh *em; | 
					
						
							| 
									
										
										
										
											2011-11-28 03:41:14 +00:00
										 |  |  | 	BMIter iter; | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	BMEdge *e; | 
					
						
							| 
									
										
										
										
											2012-05-03 21:35:04 +00:00
										 |  |  | 	float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f); | 
					
						
							| 
									
										
										
										
											2012-02-12 15:02:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-11 19:58:56 +00:00
										 |  |  | 	em = DM_to_editbmesh(dm, NULL, FALSE); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	bm = em->bm; | 
					
						
							| 
									
										
										
										
											2011-06-05 00:54:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-24 05:56:06 +00:00
										 |  |  | 	BM_mesh_normals_update(bm, FALSE); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	BMO_push(bm, NULL); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:30:19 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 		BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2011-11-28 03:41:14 +00:00
										 |  |  | 			/* check for 1 edge having 2 face users */ | 
					
						
							|  |  |  | 			BMLoop *l1, *l2; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			if ((l1 = e->l) && | 
					
						
							|  |  |  | 			    (l2 = e->l->radial_next) != l1) | 
					
						
							| 
									
										
										
										
											2011-11-28 03:41:14 +00:00
										 |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2012-07-17 17:55:23 +00:00
										 |  |  | 				if (/* 3+ faces on this edge, always split */ | 
					
						
							| 
									
										
										
										
											2012-06-05 19:24:01 +00:00
										 |  |  | 				    UNLIKELY(l1 != l2->radial_next) || | 
					
						
							|  |  |  | 				    /* 2 face edge - check angle*/ | 
					
						
							|  |  |  | 				    (dot_v3v3(l1->f->no, l2->f->no) < threshold)) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2012-02-12 18:43:59 +00:00
										 |  |  | 					BMO_elem_flag_enable(bm, e, EDGE_MARK); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:30:19 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-06-05 00:54:14 +00:00
										 |  |  | 	if (emd->flags & MOD_EDGESPLIT_FROMFLAG) { | 
					
						
							| 
									
										
										
										
											2012-04-19 13:47:58 +00:00
										 |  |  | 		BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { | 
					
						
							| 
									
										
										
										
											2012-03-05 21:17:24 +00:00
										 |  |  | 			/* check for 2 or more edge users */ | 
					
						
							|  |  |  | 			if ((e->l) && | 
					
						
							|  |  |  | 			    (e->l->next != e->l)) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) { | 
					
						
							|  |  |  | 					BMO_elem_flag_enable(bm, e, EDGE_MARK); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-02-18 11:44:30 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-06-05 00:54:14 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-06-01 19:30:19 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-04-22 23:37:58 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-07-21 00:58:02 +00:00
										 |  |  | 	BMO_op_callf(bm, BMO_FLAG_DEFAULTS, | 
					
						
							|  |  |  | 	             "split_edges edges=%fe", EDGE_MARK); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:30:19 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	BMO_pop(bm); | 
					
						
							| 
									
										
										
										
											2012-01-22 21:12:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-22 05:13:43 +00:00
										 |  |  | 	/* BM_mesh_validate(bm); */ /* for troubleshooting */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-22 21:12:18 +00:00
										 |  |  | 	BLI_assert(em->looptris == NULL); | 
					
						
							| 
									
										
										
										
											2012-02-12 15:02:33 +00:00
										 |  |  | 	result = CDDM_from_BMEditMesh(em, NULL, TRUE, FALSE); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	BMEdit_Free(em); | 
					
						
							|  |  |  | 	MEM_freeN(em); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:30:19 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-02-12 15:02:33 +00:00
										 |  |  | 	return result; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | static void initData(ModifierData *md) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-09 18:28:30 +00:00
										 |  |  | 	/* default to 30-degree split angle, sharpness from both angle & flag */ | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 	emd->split_angle = 30; | 
					
						
							|  |  |  | 	emd->flags = MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | static void copyData(ModifierData *md, ModifierData *target) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md; | 
					
						
							|  |  |  | 	EdgeSplitModifierData *temd = (EdgeSplitModifierData *) target; | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	temd->split_angle = emd->split_angle; | 
					
						
							|  |  |  | 	temd->flags = emd->flags; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DerivedMesh *edgesplitModifier_do(EdgeSplitModifierData *emd, | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |                                          Object *ob, DerivedMesh *dm) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (!(emd->flags & (MOD_EDGESPLIT_FROMANGLE | MOD_EDGESPLIT_FROMFLAG))) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		return dm; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-01 19:47:21 +00:00
										 |  |  | 	return doEdgeSplit(dm, emd, ob); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-09 15:00:26 +00:00
										 |  |  | static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, | 
					
						
							|  |  |  |                                   ModifierApplyFlag UNUSED(flag)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	DerivedMesh *result; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	EdgeSplitModifierData *emd = (EdgeSplitModifierData *) md; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	result = edgesplitModifier_do(emd, ob, derivedData); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (result != derivedData) | 
					
						
							| 
									
										
										
										
											2012-01-20 13:25:54 +00:00
										 |  |  | 		CDDM_calc_normals(result); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-19 04:44:37 +00:00
										 |  |  | static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob, | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |                                     struct BMEditMesh *UNUSED(editData), | 
					
						
							|  |  |  |                                     DerivedMesh *derivedData) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-09 15:00:26 +00:00
										 |  |  | 	return applyModifier(md, ob, derivedData, MOD_APPLY_USECACHE); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ModifierTypeInfo modifierType_EdgeSplit = { | 
					
						
							|  |  |  | 	/* name */              "EdgeSplit", | 
					
						
							|  |  |  | 	/* structName */        "EdgeSplitModifierData", | 
					
						
							|  |  |  | 	/* structSize */        sizeof(EdgeSplitModifierData), | 
					
						
							|  |  |  | 	/* type */              eModifierTypeType_Constructive, | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	/* flags */             eModifierTypeFlag_AcceptsMesh | | 
					
						
							|  |  |  | 	                        eModifierTypeFlag_AcceptsCVs | | 
					
						
							|  |  |  | 	                        eModifierTypeFlag_SupportsMapping | | 
					
						
							|  |  |  | 	                        eModifierTypeFlag_SupportsEditmode | | 
					
						
							|  |  |  | 	                        eModifierTypeFlag_EnableInEditmode, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* copyData */          copyData, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* deformVerts */       NULL, | 
					
						
							|  |  |  | 	/* deformMatrices */    NULL, | 
					
						
							|  |  |  | 	/* deformVertsEM */     NULL, | 
					
						
							|  |  |  | 	/* deformMatricesEM */  NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* applyModifier */     applyModifier, | 
					
						
							|  |  |  | 	/* applyModifierEM */   applyModifierEM, | 
					
						
							|  |  |  | 	/* initData */          initData, | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  | 	/* requiredDataMask */  NULL, | 
					
						
							|  |  |  | 	/* freeData */          NULL, | 
					
						
							|  |  |  | 	/* isDisabled */        NULL, | 
					
						
							|  |  |  | 	/* updateDepgraph */    NULL, | 
					
						
							|  |  |  | 	/* dependsOnTime */     NULL, | 
					
						
							|  |  |  | 	/* dependsOnNormals */	NULL, | 
					
						
							|  |  |  | 	/* foreachObjectLink */ NULL, | 
					
						
							|  |  |  | 	/* foreachIDLink */     NULL, | 
					
						
							| 
									
										
										
										
											2011-08-12 18:11:22 +00:00
										 |  |  | 	/* foreachTexLink */    NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | }; |