| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-01-01 16:09:32 +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) 2011 by Nicholas Bishop. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/modifiers/intern/MOD_remesh.c
 | 
					
						
							|  |  |  |  *  \ingroup modifiers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-16 08:11:07 +00:00
										 |  |  | #include "BLI_math_base.h"
 | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | #include "BLI_math_vector.h"
 | 
					
						
							|  |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_cdderivedmesh.h"
 | 
					
						
							|  |  |  | #include "BKE_DerivedMesh.h"
 | 
					
						
							|  |  |  | #include "BKE_mesh.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							|  |  |  | #include "DNA_modifier_types.h"
 | 
					
						
							|  |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "MOD_modifiertypes.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <assert.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | #ifdef WITH_MOD_REMESH
 | 
					
						
							|  |  |  | #  include "dualcon.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void initData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	RemeshModifierData *rmd = (RemeshModifierData *) md; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	rmd->scale = 0.9; | 
					
						
							|  |  |  | 	rmd->depth = 4; | 
					
						
							|  |  |  | 	rmd->hermite_num = 1; | 
					
						
							|  |  |  | 	rmd->flag = MOD_REMESH_FLOOD_FILL; | 
					
						
							|  |  |  | 	rmd->mode = MOD_REMESH_SHARP_FEATURES; | 
					
						
							|  |  |  | 	rmd->threshold = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void copyData(ModifierData *md, ModifierData *target) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	RemeshModifierData *rmd = (RemeshModifierData *) md; | 
					
						
							|  |  |  | 	RemeshModifierData *trmd = (RemeshModifierData *) target; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	trmd->threshold = rmd->threshold; | 
					
						
							|  |  |  | 	trmd->scale = rmd->scale; | 
					
						
							|  |  |  | 	trmd->hermite_num = rmd->hermite_num; | 
					
						
							|  |  |  | 	trmd->depth = rmd->depth; | 
					
						
							|  |  |  | 	trmd->flag = rmd->flag; | 
					
						
							|  |  |  | 	trmd->mode = rmd->mode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | #ifdef WITH_MOD_REMESH
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void init_dualcon_mesh(DualConInput *mesh, DerivedMesh *dm) | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	memset(mesh, 0, sizeof(DualConInput)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	mesh->co = (void *)dm->getVertArray(dm); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	mesh->co_stride = sizeof(MVert); | 
					
						
							|  |  |  | 	mesh->totco = dm->getNumVerts(dm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	mesh->faces = (void *)dm->getTessFaceArray(dm); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	mesh->face_stride = sizeof(MFace); | 
					
						
							| 
									
										
										
										
											2011-12-31 12:58:03 +00:00
										 |  |  | 	mesh->totface = dm->getNumTessFaces(dm); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-06-04 23:53:59 +00:00
										 |  |  | 	INIT_MINMAX(mesh->min, mesh->max); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	dm->getMinMax(dm, mesh->min, mesh->max); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* simple structure to hold the output: a CDDM and two counters to
 | 
					
						
							| 
									
										
										
										
											2012-03-09 18:28:30 +00:00
										 |  |  |  * keep track of the current elements */ | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | typedef struct { | 
					
						
							|  |  |  | 	DerivedMesh *dm; | 
					
						
							|  |  |  | 	int curvert, curface; | 
					
						
							|  |  |  | } DualConOutput; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* allocate and initialize a DualConOutput */ | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | static void *dualcon_alloc_output(int totvert, int totquad) | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	DualConOutput *output; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (!(output = MEM_callocN(sizeof(DualConOutput), | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	                           "DualConOutput"))) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	output->dm = CDDM_new(totvert, 0, 0, 4 * totquad, totquad); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	return output; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | static void dualcon_add_vert(void *output_v, const float co[3]) | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	DualConOutput *output = output_v; | 
					
						
							|  |  |  | 	DerivedMesh *dm = output->dm; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	assert(output->curvert < dm->getNumVerts(dm)); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	copy_v3_v3(CDDM_get_verts(dm)[output->curvert].co, co); | 
					
						
							|  |  |  | 	output->curvert++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | static void dualcon_add_quad(void *output_v, const int vert_indices[4]) | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	DualConOutput *output = output_v; | 
					
						
							|  |  |  | 	DerivedMesh *dm = output->dm; | 
					
						
							| 
									
										
										
										
											2012-02-07 01:20:49 +00:00
										 |  |  | 	MLoop *mloop; | 
					
						
							|  |  |  | 	MPoly *cur_poly; | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-02-07 01:20:49 +00:00
										 |  |  | 	assert(output->curface < dm->getNumPolys(dm)); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-07 01:20:49 +00:00
										 |  |  | 	mloop = CDDM_get_loops(dm); | 
					
						
							|  |  |  | 	cur_poly = CDDM_get_poly(dm, output->curface); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2012-02-07 01:20:49 +00:00
										 |  |  | 	cur_poly->loopstart = output->curface * 4; | 
					
						
							|  |  |  | 	cur_poly->totloop = 4; | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	for (i = 0; i < 4; i++) | 
					
						
							| 
									
										
										
										
											2012-02-07 01:20:49 +00:00
										 |  |  | 		mloop[output->curface * 4 + i].v = vert_indices[i]; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	output->curface++; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DerivedMesh *applyModifier(ModifierData *md, | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |                                   Object *UNUSED(ob), | 
					
						
							|  |  |  |                                   DerivedMesh *dm, | 
					
						
							| 
									
										
										
										
											2012-05-09 15:00:26 +00:00
										 |  |  |                                   ModifierApplyFlag UNUSED(flag)) | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	RemeshModifierData *rmd; | 
					
						
							|  |  |  | 	DualConOutput *output; | 
					
						
							|  |  |  | 	DualConInput input; | 
					
						
							|  |  |  | 	DerivedMesh *result; | 
					
						
							|  |  |  | 	DualConFlags flags = 0; | 
					
						
							| 
									
										
										
										
											2012-01-01 16:09:32 +00:00
										 |  |  | 	DualConMode mode = 0; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-05 12:40:09 +00:00
										 |  |  | 	DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	rmd = (RemeshModifierData *)md; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	init_dualcon_mesh(&input, dm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (rmd->flag & MOD_REMESH_FLOOD_FILL) | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 		flags |= DUALCON_FLOOD_FILL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-28 06:31:57 +00:00
										 |  |  | 	switch (rmd->mode) { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		case MOD_REMESH_CENTROID: | 
					
						
							|  |  |  | 			mode = DUALCON_CENTROID; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MOD_REMESH_MASS_POINT: | 
					
						
							|  |  |  | 			mode = DUALCON_MASS_POINT; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case MOD_REMESH_SHARP_FEATURES: | 
					
						
							|  |  |  | 			mode = DUALCON_SHARP_FEATURES; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	output = dualcon(&input, | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	                 dualcon_alloc_output, | 
					
						
							|  |  |  | 	                 dualcon_add_vert, | 
					
						
							|  |  |  | 	                 dualcon_add_quad, | 
					
						
							|  |  |  | 	                 flags, | 
					
						
							|  |  |  | 	                 mode, | 
					
						
							|  |  |  | 	                 rmd->threshold, | 
					
						
							|  |  |  | 	                 rmd->hermite_num, | 
					
						
							|  |  |  | 	                 rmd->scale, | 
					
						
							|  |  |  | 	                 rmd->depth); | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	result = output->dm; | 
					
						
							|  |  |  | 	MEM_freeN(output); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-18 06:10:47 +00:00
										 |  |  | 	if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) { | 
					
						
							|  |  |  | 		MPoly *mpoly = CDDM_get_polys(result); | 
					
						
							|  |  |  | 		int i, totpoly = result->getNumPolys(result); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* Apply smooth shading to output faces */ | 
					
						
							|  |  |  | 		for (i = 0; i < totpoly; i++) { | 
					
						
							|  |  |  | 			mpoly[i].flag |= ME_SMOOTH; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-29 22:13:08 +00:00
										 |  |  | 	CDDM_calc_edges(result); | 
					
						
							| 
									
										
										
										
											2013-05-30 17:36:43 +00:00
										 |  |  | 	result->dirty |= DM_DIRTY_NORMALS; | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | #else /* !WITH_MOD_REMESH */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |                                   DerivedMesh *derivedData, | 
					
						
							| 
									
										
										
										
											2012-05-09 15:00:26 +00:00
										 |  |  |                                   ModifierApplyFlag UNUSED(flag)) | 
					
						
							| 
									
										
										
										
											2011-12-31 03:34:44 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return derivedData; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* !WITH_MOD_REMESH */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | ModifierTypeInfo modifierType_Remesh = { | 
					
						
							|  |  |  | 	/* name */              "Remesh", | 
					
						
							|  |  |  | 	/* structName */        "RemeshModifierData", | 
					
						
							|  |  |  | 	/* structSize */        sizeof(RemeshModifierData), | 
					
						
							|  |  |  | 	/* type */              eModifierTypeType_Nonconstructive, | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	/* flags */             eModifierTypeFlag_AcceptsMesh | | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  | 	                        eModifierTypeFlag_AcceptsCVs | | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	                        eModifierTypeFlag_SupportsEditmode, | 
					
						
							| 
									
										
										
										
											2011-12-30 21:11:40 +00:00
										 |  |  | 	/* copyData */          copyData, | 
					
						
							|  |  |  | 	/* deformVerts */       NULL, | 
					
						
							|  |  |  | 	/* deformMatrices */    NULL, | 
					
						
							|  |  |  | 	/* deformVertsEM */     NULL, | 
					
						
							|  |  |  | 	/* deformMatricesEM */  NULL, | 
					
						
							|  |  |  | 	/* applyModifier */     applyModifier, | 
					
						
							|  |  |  | 	/* applyModifierEM */   NULL, | 
					
						
							|  |  |  | 	/* initData */          initData, | 
					
						
							|  |  |  | 	/* requiredDataMask */  NULL, | 
					
						
							|  |  |  | 	/* freeData */          NULL, | 
					
						
							|  |  |  | 	/* isDisabled */        NULL, | 
					
						
							|  |  |  | 	/* updateDepgraph */    NULL, | 
					
						
							|  |  |  | 	/* dependsOnTime */     NULL, | 
					
						
							|  |  |  | 	/* dependsOnNormals */	NULL, | 
					
						
							|  |  |  | 	/* foreachObjectLink */ NULL, | 
					
						
							|  |  |  | 	/* foreachIDLink */     NULL, | 
					
						
							|  |  |  | }; |