| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-10-23 17:52:20 +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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2005 by the Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-25 13:57:17 +00:00
										 |  |  | /** \file blender/modifiers/intern/MOD_solidify.c
 | 
					
						
							|  |  |  |  *  \ingroup modifiers | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 14:32:53 +00:00
										 |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-12-28 09:47:24 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-05-09 04:06:48 +00:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-19 20:16:05 +10:00
										 |  |  | #include "BLI_utildefines_stack.h"
 | 
					
						
							| 
									
										
										
										
											2014-01-16 17:46:32 +06:00
										 |  |  | #include "BLI_bitmap.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-12 00:36:50 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_mesh.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | #include "BKE_particle.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #include "BKE_deform.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:18:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #include "MOD_modifiertypes.h"
 | 
					
						
							| 
									
										
										
										
											2011-07-11 09:15:20 +00:00
										 |  |  | #include "MOD_util.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | #ifdef __GNUC__
 | 
					
						
							|  |  |  | #  pragma GCC diagnostic error "-Wsign-conversion"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 10:03:13 +00:00
										 |  |  | /* skip shell thickness for non-manifold edges, see [#35710] */ | 
					
						
							|  |  |  | #define USE_NONMANIFOLD_WORKAROUND
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-26 09:18:47 +00:00
										 |  |  | /* *** derived mesh high quality normal calculation function  *** */ | 
					
						
							|  |  |  | /* could be exposed for other functions to use */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | typedef struct EdgeFaceRef { | 
					
						
							|  |  |  | 	int f1; /* init as -1 */ | 
					
						
							|  |  |  | 	int f2; | 
					
						
							|  |  |  | } EdgeFaceRef; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 07:16:13 +00:00
										 |  |  | BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 	return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0)); | 
					
						
							| 
									
										
										
										
											2013-06-12 07:16:13 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-03 14:02:05 +02:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-12-12 12:50:58 +11:00
										 |  |  |  * \param dm: Mesh to calculate normals for. | 
					
						
							|  |  |  |  * \param face_nors: Precalculated face normals. | 
					
						
							|  |  |  |  * \param r_vert_nors: Return vert normals. | 
					
						
							| 
									
										
										
										
											2018-05-03 14:02:05 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | static void mesh_calc_hq_normal(Mesh *mesh, float (*face_nors)[3], float (*r_vert_nors)[3]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, numVerts, numEdges, numFaces; | 
					
						
							|  |  |  | 	MPoly *mpoly, *mp; | 
					
						
							|  |  |  | 	MLoop *mloop, *ml; | 
					
						
							|  |  |  | 	MEdge *medge, *ed; | 
					
						
							|  |  |  | 	MVert *mvert, *mv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	numVerts = mesh->totvert; | 
					
						
							|  |  |  | 	numEdges = mesh->totedge; | 
					
						
							|  |  |  | 	numFaces = mesh->totface; | 
					
						
							|  |  |  | 	mpoly = mesh->mpoly; | 
					
						
							|  |  |  | 	medge = mesh->medge; | 
					
						
							|  |  |  | 	mvert = mesh->mvert; | 
					
						
							|  |  |  | 	mloop = mesh->mloop; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* we don't want to overwrite any referenced layers */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Doesn't work here! */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							|  |  |  | 	mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts); | 
					
						
							|  |  |  | 	cddm->mvert = mv; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mv = mvert; | 
					
						
							|  |  |  | 	mp = mpoly; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN((size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity"); | 
					
						
							|  |  |  | 		EdgeFaceRef *edge_ref; | 
					
						
							|  |  |  | 		float edge_normal[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-03 19:48:28 +02:00
										 |  |  | 		/* Add an edge reference if it's not there, pointing back to the face index. */ | 
					
						
							| 
									
										
										
										
											2018-05-03 14:02:05 +02:00
										 |  |  | 		for (i = 0; i < numFaces; i++, mp++) { | 
					
						
							|  |  |  | 			int j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ml = mloop + mp->loopstart; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (j = 0; j < mp->totloop; j++, ml++) { | 
					
						
							|  |  |  | 				/* --- add edge ref to face --- */ | 
					
						
							|  |  |  | 				edge_ref = &edge_ref_array[ml->e]; | 
					
						
							|  |  |  | 				if (!edgeref_is_init(edge_ref)) { | 
					
						
							|  |  |  | 					edge_ref->f1 =  i; | 
					
						
							|  |  |  | 					edge_ref->f2 = -1; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else if ((edge_ref->f1 != -1) && (edge_ref->f2 == -1)) { | 
					
						
							|  |  |  | 					edge_ref->f2 = i; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					/* 3+ faces using an edge, we can't handle this usefully */ | 
					
						
							|  |  |  | 					edge_ref->f1 = edge_ref->f2 = -1; | 
					
						
							|  |  |  | #ifdef USE_NONMANIFOLD_WORKAROUND
 | 
					
						
							|  |  |  | 					medge[ml->e].flag |= ME_EDGE_TMP_TAG; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				/* --- done --- */ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) { | 
					
						
							|  |  |  | 			/* Get the edge vert indices, and edge value (the face indices that use it) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (edgeref_is_init(edge_ref) && (edge_ref->f1 != -1)) { | 
					
						
							|  |  |  | 				if (edge_ref->f2 != -1) { | 
					
						
							|  |  |  | 					/* We have 2 faces using this edge, calculate the edges normal
 | 
					
						
							| 
									
										
										
										
											2013-06-12 07:53:54 +00:00
										 |  |  | 					 * using the angle between the 2 faces as a weighting */ | 
					
						
							| 
									
										
										
										
											2018-05-03 14:02:05 +02:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 					add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); | 
					
						
							|  |  |  | 					normalize_v3_length( | 
					
						
							| 
									
										
										
										
											2016-07-08 10:14:49 +10:00
										 |  |  | 					        edge_normal, | 
					
						
							|  |  |  | 					        angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); | 
					
						
							| 
									
										
										
										
											2018-05-03 14:02:05 +02:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 					mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					/* only one face attached to that edge */ | 
					
						
							|  |  |  | 					/* an edge without another attached- the weight on this is undefined */ | 
					
						
							|  |  |  | 					copy_v3_v3(edge_normal, face_nors[edge_ref->f1]); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				add_v3_v3(r_vert_nors[ed->v1], edge_normal); | 
					
						
							|  |  |  | 				add_v3_v3(r_vert_nors[ed->v2], edge_normal); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		MEM_freeN(edge_ref_array); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* normalize vertex normals and assign */ | 
					
						
							|  |  |  | 	for (i = 0; i < numVerts; i++, mv++) { | 
					
						
							|  |  |  | 		if (normalize_v3(r_vert_nors[i]) == 0.0f) { | 
					
						
							|  |  |  | 			normal_short_to_float_v3(r_vert_nors[i], mv->no); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | static void initData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	SolidifyModifierData *smd = (SolidifyModifierData *) md; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	smd->offset = 0.01f; | 
					
						
							| 
									
										
										
										
											2010-07-14 08:24:24 +00:00
										 |  |  | 	smd->offset_fac = -1.0f; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	smd->flag = MOD_SOLIDIFY_RIM; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-05-23 06:25:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-14 06:29:17 +00:00
										 |  |  | static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) | 
					
						
							| 
									
										
										
										
											2010-06-03 22:08:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	SolidifyModifierData *smd = (SolidifyModifierData *) md; | 
					
						
							| 
									
										
										
										
											2010-06-03 22:08:14 +00:00
										 |  |  | 	CustomDataMask dataMask = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ask for vertexgroups if we need them */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (smd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT; | 
					
						
							| 
									
										
										
										
											2010-06-03 22:08:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return dataMask; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-07-16 23:23:33 +00:00
										 |  |  | /* specific function for solidify - define locally */ | 
					
						
							| 
									
										
										
										
											2012-05-26 09:18:47 +00:00
										 |  |  | BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	r[0] += (float)a[0] * f; | 
					
						
							|  |  |  | 	r[1] += (float)a[1] * f; | 
					
						
							|  |  |  | 	r[2] += (float)a[2] * f; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-06-03 22:08:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | static Mesh *applyModifier( | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |         ModifierData *md, const ModifierEvalContext *ctx, | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  |         Mesh *mesh) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	Mesh *result; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	const SolidifyModifierData *smd = (SolidifyModifierData *) md; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	MVert *mv, *mvert, *orig_mvert; | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 	MEdge *ed, *medge, *orig_medge; | 
					
						
							|  |  |  | 	MLoop *ml, *mloop, *orig_mloop; | 
					
						
							|  |  |  | 	MPoly *mp, *mpoly, *orig_mpoly; | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	const unsigned int numVerts = (unsigned int)mesh->totvert; | 
					
						
							|  |  |  | 	const unsigned int numEdges = (unsigned int)mesh->totedge; | 
					
						
							|  |  |  | 	const unsigned int numFaces = (unsigned int)mesh->totpoly; | 
					
						
							|  |  |  | 	const unsigned int numLoops = (unsigned int)mesh->totloop; | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 	unsigned int newLoops = 0, newFaces = 0, newEdges = 0, newVerts = 0, rimVerts = 0; | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-03 05:09:07 +00:00
										 |  |  | 	/* only use material offsets if we have 2 or more materials  */ | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  | 	const short mat_nr_max = ctx->object->totcol > 1 ? ctx->object->totcol - 1 : 0; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	const short mat_ofs = mat_nr_max ? smd->mat_ofs : 0; | 
					
						
							|  |  |  | 	const short mat_ofs_rim = mat_nr_max ? smd->mat_ofs_rim : 0; | 
					
						
							| 
									
										
										
										
											2011-03-03 05:09:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* use for edges */ | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 	/* over-alloc new_vert_arr, old_vert_arr */ | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 	unsigned int *new_vert_arr = NULL; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 	STACK_DECLARE(new_vert_arr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 	unsigned int *new_edge_arr = NULL; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 	STACK_DECLARE(new_edge_arr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 	unsigned int *old_vert_arr = MEM_calloc_arrayN(numVerts, sizeof(*old_vert_arr), "old_vert_arr in solidify"); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 	unsigned int *edge_users = NULL; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	char *edge_order = NULL; | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	float (*vert_nors)[3] = NULL; | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 	float (*face_nors)[3] = NULL; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 	const bool need_face_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN); | 
					
						
							| 
									
										
										
										
											2012-02-26 18:12:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 09:53:33 +00:00
										 |  |  | 	const float ofs_orig = -(((-smd->offset_fac + 1.0f) * 0.5f) * smd->offset); | 
					
						
							| 
									
										
										
										
											2012-05-22 10:10:14 +00:00
										 |  |  | 	const float ofs_new  = smd->offset + ofs_orig; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 	const float offset_fac_vg = smd->offset_fac_vg; | 
					
						
							|  |  |  | 	const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg; | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 	const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0; | 
					
						
							|  |  |  | 	const bool do_clamp = (smd->offset_clamp != 0.0f); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	const bool do_shell = ((smd->flag & MOD_SOLIDIFY_RIM) && (smd->flag & MOD_SOLIDIFY_NOSHELL)) == 0; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* weights */ | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 	MDeformVert *dvert; | 
					
						
							| 
									
										
										
										
											2015-04-20 23:37:04 +10:00
										 |  |  | 	const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; | 
					
						
							| 
									
										
										
										
											2011-07-11 09:15:20 +00:00
										 |  |  | 	int defgrp_index; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	/* array size is doubled in case of using a shell */ | 
					
						
							|  |  |  | 	const unsigned int stride = do_shell ? 2 : 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-29 19:02:19 +02:00
										 |  |  | 	MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); | 
					
						
							| 
									
										
										
										
											2012-01-19 23:51:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	orig_mvert = mesh->mvert; | 
					
						
							|  |  |  | 	orig_medge = mesh->medge; | 
					
						
							|  |  |  | 	orig_mloop = mesh->mloop; | 
					
						
							|  |  |  | 	orig_mpoly = mesh->mpoly; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 	if (need_face_normals) { | 
					
						
							|  |  |  | 		/* calculate only face normals */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		face_nors = MEM_malloc_arrayN(numFaces, sizeof(*face_nors), __func__); | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 		BKE_mesh_calc_normals_poly( | 
					
						
							| 
									
										
										
										
											2015-10-12 20:12:55 +02:00
										 |  |  | 		            orig_mvert, NULL, (int)numVerts, | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 		            orig_mloop, orig_mpoly, | 
					
						
							|  |  |  | 		            (int)numLoops, (int)numFaces, | 
					
						
							|  |  |  | 		            face_nors, true); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-29 05:06:22 +10:00
										 |  |  | 	STACK_INIT(new_vert_arr, numVerts * 2); | 
					
						
							|  |  |  | 	STACK_INIT(new_edge_arr, numEdges * 2); | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (smd->flag & MOD_SOLIDIFY_RIM) { | 
					
						
							| 
									
										
										
										
											2014-01-17 06:58:09 +11:00
										 |  |  | 		BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__); | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 		unsigned int eidx; | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		unsigned int i; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | #define INVALID_UNUSED ((unsigned int)-1)
 | 
					
						
							|  |  |  | #define INVALID_PAIR ((unsigned int)-2)
 | 
					
						
							| 
									
										
										
										
											2012-05-22 09:53:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		new_vert_arr = MEM_malloc_arrayN(numVerts, 2 * sizeof(*new_vert_arr), __func__); | 
					
						
							|  |  |  | 		new_edge_arr = MEM_malloc_arrayN(((numEdges * 2) + numVerts), sizeof(*new_edge_arr), __func__); | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges"); | 
					
						
							|  |  |  | 		edge_order = MEM_malloc_arrayN(numEdges, sizeof(*edge_order), "solid_mod eorder"); | 
					
						
							| 
									
										
										
										
											2012-05-22 09:53:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-17 06:58:09 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-22 09:53:33 +00:00
										 |  |  | 		/* save doing 2 loops here... */ | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2015-05-05 17:08:29 +10:00
										 |  |  | 		copy_vn_i(edge_users, numEdges, INVALID_UNUSED); | 
					
						
							| 
									
										
										
										
											2012-05-22 09:53:33 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 07:16:13 +00:00
										 |  |  | 		for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { | 
					
						
							|  |  |  | 			edge_users[eidx] = INVALID_UNUSED; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		for (i = 0, mp = orig_mpoly; i < numFaces; i++, mp++) { | 
					
						
							| 
									
										
										
										
											2013-06-15 08:59:54 +00:00
										 |  |  | 			MLoop *ml_prev; | 
					
						
							| 
									
										
										
										
											2012-10-20 09:56:40 +00:00
										 |  |  | 			int j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ml = orig_mloop + mp->loopstart; | 
					
						
							| 
									
										
										
										
											2013-06-15 08:59:54 +00:00
										 |  |  | 			ml_prev = ml + (mp->totloop - 1); | 
					
						
							| 
									
										
										
										
											2012-05-22 10:10:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-14 16:10:32 +00:00
										 |  |  | 			for (j = 0; j < mp->totloop; j++, ml++) { | 
					
						
							| 
									
										
										
										
											2012-05-22 10:10:14 +00:00
										 |  |  | 				/* add edge user */ | 
					
						
							| 
									
										
										
										
											2013-06-15 08:59:54 +00:00
										 |  |  | 				eidx = ml_prev->e; | 
					
						
							| 
									
										
										
										
											2012-05-22 10:10:14 +00:00
										 |  |  | 				if (edge_users[eidx] == INVALID_UNUSED) { | 
					
						
							|  |  |  | 					ed = orig_medge + eidx; | 
					
						
							| 
									
										
										
										
											2013-06-15 08:59:54 +00:00
										 |  |  | 					BLI_assert(ELEM(ml_prev->v,    ed->v1, ed->v2) && | 
					
						
							|  |  |  | 					           ELEM(ml->v, ed->v1, ed->v2)); | 
					
						
							|  |  |  | 					edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + numFaces); | 
					
						
							| 
									
										
										
										
											2012-05-22 10:10:14 +00:00
										 |  |  | 					edge_order[eidx] = j; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					edge_users[eidx] = INVALID_PAIR; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-06-15 08:59:54 +00:00
										 |  |  | 				ml_prev = ml; | 
					
						
							| 
									
										
										
										
											2012-05-22 10:10:14 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 07:16:13 +00:00
										 |  |  | 		for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) { | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 			if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) { | 
					
						
							| 
									
										
										
										
											2014-06-06 16:05:15 +10:00
										 |  |  | 				BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v1); | 
					
						
							|  |  |  | 				BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v2); | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 				STACK_PUSH(new_edge_arr, eidx); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				newFaces++; | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 				newLoops += 4; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-16 17:46:32 +06:00
										 |  |  | 		for (i = 0; i < numVerts; i++) { | 
					
						
							| 
									
										
										
										
											2014-06-06 16:05:15 +10:00
										 |  |  | 			if (BLI_BITMAP_TEST(orig_mvert_tag, i)) { | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 				old_vert_arr[i] = STACK_SIZE(new_vert_arr); | 
					
						
							|  |  |  | 				STACK_PUSH(new_vert_arr, i); | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 				rimVerts++; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			else { | 
					
						
							|  |  |  | 				old_vert_arr[i] = INVALID_UNUSED; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-01-17 06:58:09 +11:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		MEM_freeN(orig_mvert_tag); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 	if (do_shell == false) { | 
					
						
							|  |  |  | 		/* only add rim vertices */ | 
					
						
							|  |  |  | 		newVerts = rimVerts; | 
					
						
							|  |  |  | 		/* each extruded face needs an opposite edge */ | 
					
						
							|  |  |  | 		newEdges = newFaces; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* (stride == 2) in this case, so no need to add newVerts/newEdges */ | 
					
						
							|  |  |  | 		BLI_assert(newVerts == 0); | 
					
						
							|  |  |  | 		BLI_assert(newEdges == 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		vert_nors = MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno_hq"); | 
					
						
							| 
									
										
										
										
											2018-05-03 14:02:05 +02:00
										 |  |  | 		mesh_calc_hq_normal(mesh, face_nors, vert_nors); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:06:30 +02:00
										 |  |  | 	result = BKE_mesh_new_nomain_from_template( | 
					
						
							|  |  |  | 	        mesh, | 
					
						
							|  |  |  | 	        (int)((numVerts * stride) + newVerts), | 
					
						
							|  |  |  | 	        (int)((numEdges * stride) + newEdges + rimVerts), 0, | 
					
						
							|  |  |  | 	        (int)((numLoops * stride) + newLoops), | 
					
						
							|  |  |  | 	        (int)((numFaces * stride) + newFaces)); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	mpoly = result->mpoly; | 
					
						
							|  |  |  | 	mloop = result->mloop; | 
					
						
							|  |  |  | 	medge = result->medge; | 
					
						
							|  |  |  | 	mvert = result->mvert; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	if (do_shell) { | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts); | 
					
						
							|  |  |  | 		CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)numVerts, (int)numVerts); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges); | 
					
						
							|  |  |  | 		CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)numEdges, (int)numEdges); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops); | 
					
						
							| 
									
										
										
										
											2019-01-28 21:46:05 +01:00
										 |  |  | 		/* DO NOT copy here the 'copied' part of loop data, we want to reverse loops
 | 
					
						
							|  |  |  | 		 * (so that winding of copied face get reversed, so that normals get reversed | 
					
						
							|  |  |  | 		 * and point in expected direction...). | 
					
						
							|  |  |  | 		 * If we also copy data here, then this data get overwritten (and allocated memory becomes memleak). */ | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numFaces); | 
					
						
							|  |  |  | 		CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)numFaces, (int)numFaces); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		int i, j; | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 		for (i = 0, j = (int)numVerts; i < numVerts; i++) { | 
					
						
							|  |  |  | 			if (old_vert_arr[i] != INVALID_UNUSED) { | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 				CustomData_copy_data(&mesh->vdata, &result->vdata, i, j, 1); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				j++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-02-11 21:39:09 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2011-03-03 05:09:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		for (i = 0, j = (int)numEdges; i < numEdges; i++) { | 
					
						
							|  |  |  | 			if (!ELEM(edge_users[i], INVALID_UNUSED, INVALID_PAIR)) { | 
					
						
							| 
									
										
										
										
											2014-08-18 16:04:44 +10:00
										 |  |  | 				MEdge *ed_src, *ed_dst; | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 				CustomData_copy_data(&mesh->edata, &result->edata, i, j, 1); | 
					
						
							| 
									
										
										
										
											2012-02-11 21:39:09 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				ed_src = &medge[i]; | 
					
						
							|  |  |  | 				ed_dst = &medge[j]; | 
					
						
							|  |  |  | 				ed_dst->v1 = old_vert_arr[ed_src->v1] + numVerts; | 
					
						
							|  |  |  | 				ed_dst->v2 = old_vert_arr[ed_src->v2] + numVerts; | 
					
						
							|  |  |  | 				j++; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 		/* will be created later */ | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops); | 
					
						
							|  |  |  | 		CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numFaces); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef INVALID_UNUSED
 | 
					
						
							|  |  |  | #undef INVALID_PAIR
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* initializes: (i_end, do_shell_align, mv)  */ | 
					
						
							|  |  |  | #define INIT_VERT_ARRAY_OFFSETS(test) \
 | 
					
						
							|  |  |  | 	if (((ofs_new >= ofs_orig) == do_flip) == test) { \ | 
					
						
							|  |  |  | 		i_end = numVerts; \ | 
					
						
							|  |  |  | 		do_shell_align = true; \ | 
					
						
							|  |  |  | 		mv = mvert; \ | 
					
						
							|  |  |  | 	} \ | 
					
						
							|  |  |  | 	else { \ | 
					
						
							|  |  |  | 		if (do_shell) { \ | 
					
						
							|  |  |  | 			i_end = numVerts; \ | 
					
						
							|  |  |  | 			do_shell_align = true; \ | 
					
						
							|  |  |  | 		} \ | 
					
						
							|  |  |  | 		else { \ | 
					
						
							|  |  |  | 			i_end = newVerts ; \ | 
					
						
							|  |  |  | 			do_shell_align = false; \ | 
					
						
							|  |  |  | 		} \ | 
					
						
							|  |  |  | 		mv = &mvert[numVerts]; \ | 
					
						
							|  |  |  | 	} (void)0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	/* flip normals */ | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	if (do_shell) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 		mp = mpoly + numFaces; | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		for (i = 0; i < mesh->totpoly; i++, mp++) { | 
					
						
							| 
									
										
										
										
											2016-04-11 22:56:17 +10:00
										 |  |  | 			const int loop_end = mp->totloop - 1; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			MLoop *ml2; | 
					
						
							|  |  |  | 			unsigned int e; | 
					
						
							|  |  |  | 			int j; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-04 06:17:32 +11:00
										 |  |  | 			/* reverses the loop direction (MLoop.v as well as custom-data)
 | 
					
						
							|  |  |  | 			 * MLoop.e also needs to be corrected too, done in a separate loop below. */ | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 			ml2 = mloop + mp->loopstart + mesh->totloop; | 
					
						
							| 
									
										
										
										
											2016-04-11 22:56:17 +10:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			for (j = 0; j < mp->totloop; j++) { | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 				CustomData_copy_data(&mesh->ldata, &result->ldata, mp->loopstart + j, | 
					
						
							|  |  |  | 				                     mp->loopstart + (loop_end - j) + mesh->totloop, 1); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-04-11 22:56:17 +10:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 			/* slightly more involved, keep the first vertex the same for the copy,
 | 
					
						
							|  |  |  | 			 * ensures the diagonals in the new face match the original. */ | 
					
						
							|  |  |  | 			j = 0; | 
					
						
							|  |  |  | 			for (int j_prev = loop_end; j < mp->totloop; j_prev = j++) { | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 				CustomData_copy_data(&mesh->ldata, &result->ldata, mp->loopstart + j, | 
					
						
							|  |  |  | 				                     mp->loopstart + (loop_end - j_prev) + mesh->totloop, 1); | 
					
						
							| 
									
										
										
										
											2016-04-11 22:56:17 +10:00
										 |  |  | 			} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if (mat_ofs) { | 
					
						
							|  |  |  | 				mp->mat_nr += mat_ofs; | 
					
						
							|  |  |  | 				CLAMP(mp->mat_nr, 0, mat_nr_max); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			e = ml2[0].e; | 
					
						
							| 
									
										
										
										
											2016-04-11 22:56:17 +10:00
										 |  |  | 			for (j = 0; j < loop_end; j++) { | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				ml2[j].e = ml2[j + 1].e; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-04-11 22:56:17 +10:00
										 |  |  | 			ml2[loop_end].e = e; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 			mp->loopstart += mesh->totloop; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			for (j = 0; j < mp->totloop; j++) { | 
					
						
							|  |  |  | 				ml2[j].e += numEdges; | 
					
						
							|  |  |  | 				ml2[j].v += numVerts; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 		for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) { | 
					
						
							|  |  |  | 			ed->v1 += numVerts; | 
					
						
							|  |  |  | 			ed->v2 += numVerts; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-18 07:38:51 +00:00
										 |  |  | 	/* note, copied vertex layers don't have flipped normals yet. do this after applying offset */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if ((smd->flag & MOD_SOLIDIFY_EVEN) == 0) { | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		/* no even thickness, very simple */ | 
					
						
							|  |  |  | 		float scalar_short; | 
					
						
							|  |  |  | 		float scalar_short_vgroup; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 		/* for clamping */ | 
					
						
							|  |  |  | 		float *vert_lens = NULL; | 
					
						
							|  |  |  | 		const float offset    = fabsf(smd->offset) * smd->offset_clamp; | 
					
						
							|  |  |  | 		const float offset_sq = offset * offset; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (do_clamp) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 			vert_lens = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens"); | 
					
						
							| 
									
										
										
										
											2015-05-05 17:08:29 +10:00
										 |  |  | 			copy_vn_fl(vert_lens, (int)numVerts, FLT_MAX); | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 			for (i = 0; i < numEdges; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 				const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); | 
					
						
							|  |  |  | 				vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq); | 
					
						
							|  |  |  | 				vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq); | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 		if (ofs_new != 0.0f) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			unsigned int i_orig, i_end; | 
					
						
							|  |  |  | 			bool do_shell_align; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			scalar_short = scalar_short_vgroup = ofs_new / 32767.0f; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			INIT_VERT_ARRAY_OFFSETS(false); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { | 
					
						
							|  |  |  | 				const unsigned int i = do_shell_align ? i_orig : new_vert_arr[i_orig]; | 
					
						
							|  |  |  | 				if (dvert) { | 
					
						
							|  |  |  | 					MDeformVert *dv = &dvert[i]; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 					if (defgrp_invert) scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); | 
					
						
							|  |  |  | 					else scalar_short_vgroup = defvert_find_weight(dv, defgrp_index); | 
					
						
							|  |  |  | 					scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 				if (do_clamp) { | 
					
						
							|  |  |  | 					/* always reset becaise we may have set before */ | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 					if (dvert == NULL) { | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 						scalar_short_vgroup = scalar_short; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if (vert_lens[i] < offset_sq) { | 
					
						
							|  |  |  | 						float scalar = sqrtf(vert_lens[i]) / offset; | 
					
						
							|  |  |  | 						scalar_short_vgroup *= scalar; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-23 06:32:02 +00:00
										 |  |  | 				madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 		if (ofs_orig != 0.0f) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			unsigned int i_orig, i_end; | 
					
						
							|  |  |  | 			bool do_shell_align; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			scalar_short = scalar_short_vgroup = ofs_orig / 32767.0f; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* as above but swapped */ | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			INIT_VERT_ARRAY_OFFSETS(true); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { | 
					
						
							|  |  |  | 				const unsigned int i = do_shell_align ? i_orig : new_vert_arr[i_orig]; | 
					
						
							|  |  |  | 				if (dvert) { | 
					
						
							|  |  |  | 					MDeformVert *dv = &dvert[i]; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 					if (defgrp_invert) scalar_short_vgroup = 1.0f - defvert_find_weight(dv, defgrp_index); | 
					
						
							|  |  |  | 					else scalar_short_vgroup = defvert_find_weight(dv, defgrp_index); | 
					
						
							|  |  |  | 					scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 				if (do_clamp) { | 
					
						
							|  |  |  | 					/* always reset becaise we may have set before */ | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 					if (dvert == NULL) { | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 						scalar_short_vgroup = scalar_short; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if (vert_lens[i] < offset_sq) { | 
					
						
							|  |  |  | 						float scalar = sqrtf(vert_lens[i]) / offset; | 
					
						
							|  |  |  | 						scalar_short_vgroup *= scalar; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2012-05-23 06:32:02 +00:00
										 |  |  | 				madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (do_clamp) { | 
					
						
							|  |  |  | 			MEM_freeN(vert_lens); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2013-06-12 10:03:13 +00:00
										 |  |  | #ifdef USE_NONMANIFOLD_WORKAROUND
 | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 		const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0; | 
					
						
							| 
									
										
										
										
											2013-06-12 10:03:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		/* same as EM_solidify() in editmesh_lib.c */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		float *vert_angles = MEM_calloc_arrayN(numVerts, 2 * sizeof(float), "mod_solid_pair"); /* 2 in 1 */ | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		float *vert_accum = vert_angles + numVerts; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 		unsigned int vidx; | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		unsigned int i; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		if (vert_nors == NULL) { | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 			vert_nors = MEM_malloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno"); | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			for (i = 0, mv = mvert; i < numVerts; i++, mv++) { | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				normal_short_to_float_v3(vert_nors[i], mv->no); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		for (i = 0, mp = mpoly; i < numFaces; i++, mp++) { | 
					
						
							| 
									
										
										
										
											2013-05-08 12:56:51 +00:00
										 |  |  | 			/* #BKE_mesh_calc_poly_angles logic is inlined here */ | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 			float nor_prev[3]; | 
					
						
							|  |  |  | 			float nor_next[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 			int i_curr = mp->totloop - 1; | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 			int i_next = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			ml = &mloop[mp->loopstart]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 			sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co); | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 			normalize_v3(nor_prev); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			while (i_next < mp->totloop) { | 
					
						
							| 
									
										
										
										
											2012-05-07 18:07:34 +00:00
										 |  |  | 				float angle; | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 				sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co); | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 				normalize_v3(nor_next); | 
					
						
							|  |  |  | 				angle = angle_normalized_v3v3(nor_prev, nor_next); | 
					
						
							| 
									
										
										
										
											2012-05-07 15:45:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-07 18:07:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 				/* --- not related to angle calc --- */ | 
					
						
							| 
									
										
										
										
											2012-05-07 18:07:34 +00:00
										 |  |  | 				if (angle < FLT_EPSILON) { | 
					
						
							|  |  |  | 					angle = FLT_EPSILON; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 				vidx = ml[i_curr].v; | 
					
						
							| 
									
										
										
										
											2012-05-07 18:07:34 +00:00
										 |  |  | 				vert_accum[vidx] += angle; | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 10:03:13 +00:00
										 |  |  | #ifdef USE_NONMANIFOLD_WORKAROUND
 | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 				/* skip 3+ face user edges */ | 
					
						
							|  |  |  | 				if ((check_non_manifold == false) || | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 				    LIKELY(((orig_medge[ml[i_curr].e].flag & ME_EDGE_TMP_TAG) == 0) && | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 				           ((orig_medge[ml[i_next].e].flag & ME_EDGE_TMP_TAG) == 0))) | 
					
						
							|  |  |  | 				{ | 
					
						
							| 
									
										
										
										
											2014-04-19 22:12:50 +10:00
										 |  |  | 					vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], face_nors[i]) * angle; | 
					
						
							| 
									
										
										
										
											2013-06-12 08:24:31 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					vert_angles[vidx] += angle; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2013-06-12 10:03:13 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-04-19 22:12:50 +10:00
										 |  |  | 				vert_angles[vidx] += shell_v3v3_normalized_to_dist(vert_nors[vidx], face_nors[i]) * angle; | 
					
						
							| 
									
										
										
										
											2013-06-12 10:03:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 				/* --- end non-angle-calc section --- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* step */ | 
					
						
							|  |  |  | 				copy_v3_v3(nor_prev, nor_next); | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 				i_curr = i_next; | 
					
						
							| 
									
										
										
										
											2012-05-08 14:58:38 +00:00
										 |  |  | 				i_next++; | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* vertex group support */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 		if (dvert) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			MDeformVert *dv = dvert; | 
					
						
							| 
									
										
										
										
											2011-08-14 06:43:58 +00:00
										 |  |  | 			float scalar; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 			if (defgrp_invert) { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 				for (i = 0; i < numVerts; i++, dv++) { | 
					
						
							|  |  |  | 					scalar = 1.0f - defvert_find_weight(dv, defgrp_index); | 
					
						
							|  |  |  | 					scalar = offset_fac_vg + (scalar * offset_fac_vg_inv); | 
					
						
							| 
									
										
										
										
											2011-08-14 06:43:58 +00:00
										 |  |  | 					vert_angles[i] *= scalar; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 				for (i = 0; i < numVerts; i++, dv++) { | 
					
						
							|  |  |  | 					scalar = defvert_find_weight(dv, defgrp_index); | 
					
						
							|  |  |  | 					scalar = offset_fac_vg + (scalar * offset_fac_vg_inv); | 
					
						
							| 
									
										
										
										
											2011-08-14 06:43:58 +00:00
										 |  |  | 					vert_angles[i] *= scalar; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 		if (do_clamp) { | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 			float *vert_lens_sq = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens"); | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 			const float offset    = fabsf(smd->offset) * smd->offset_clamp; | 
					
						
							|  |  |  | 			const float offset_sq = offset * offset; | 
					
						
							| 
									
										
										
										
											2015-05-05 17:08:29 +10:00
										 |  |  | 			copy_vn_fl(vert_lens_sq, (int)numVerts, FLT_MAX); | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 			for (i = 0; i < numEdges; i++) { | 
					
						
							|  |  |  | 				const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 				vert_lens_sq[medge[i].v1] = min_ff(vert_lens_sq[medge[i].v1], ed_len); | 
					
						
							|  |  |  | 				vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len); | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			for (i = 0; i < numVerts; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 				if (vert_lens_sq[i] < offset_sq) { | 
					
						
							|  |  |  | 					float scalar = sqrtf(vert_lens_sq[i]) / offset; | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 					vert_angles[i] *= scalar; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-03 02:46:45 +11:00
										 |  |  | 			MEM_freeN(vert_lens_sq); | 
					
						
							| 
									
										
										
										
											2013-03-13 17:31:26 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		if (ofs_new != 0.0f) { | 
					
						
							|  |  |  | 			unsigned int i_orig, i_end; | 
					
						
							|  |  |  | 			bool do_shell_align; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			INIT_VERT_ARRAY_OFFSETS(false); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { | 
					
						
							| 
									
										
										
										
											2015-11-23 15:45:10 +11:00
										 |  |  | 				const unsigned int i_other = do_shell_align ? i_orig : new_vert_arr[i_orig]; | 
					
						
							|  |  |  | 				if (vert_accum[i_other]) { /* zero if unselected */ | 
					
						
							|  |  |  | 					madd_v3_v3fl(mv->co, vert_nors[i_other], ofs_new * (vert_angles[i_other] / vert_accum[i_other])); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		if (ofs_orig != 0.0f) { | 
					
						
							|  |  |  | 			unsigned int i_orig, i_end; | 
					
						
							|  |  |  | 			bool do_shell_align; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			/* same as above but swapped, intentional use of 'ofs_new' */ | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			INIT_VERT_ARRAY_OFFSETS(true); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 			for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { | 
					
						
							| 
									
										
										
										
											2015-11-23 15:45:10 +11:00
										 |  |  | 				const unsigned int i_other = do_shell_align ? i_orig : new_vert_arr[i_orig]; | 
					
						
							|  |  |  | 				if (vert_accum[i_other]) { /* zero if unselected */ | 
					
						
							|  |  |  | 					madd_v3_v3fl(mv->co, vert_nors[i_other], ofs_orig * (vert_angles[i_other] / vert_accum[i_other])); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		MEM_freeN(vert_angles); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (vert_nors) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		MEM_freeN(vert_nors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 	/* must recalculate normals with vgroups since they can displace unevenly [#26888] */ | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	if ((mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) || (smd->flag & MOD_SOLIDIFY_RIM) || dvert) { | 
					
						
							|  |  |  | 		result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 	else if (do_shell) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		unsigned int i; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 		/* flip vertex normals for copied verts */ | 
					
						
							|  |  |  | 		mv = mvert + numVerts; | 
					
						
							|  |  |  | 		for (i = 0; i < numVerts; i++, mv++) { | 
					
						
							|  |  |  | 			negate_v3_short(mv->no); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 	if (smd->flag & MOD_SOLIDIFY_RIM) { | 
					
						
							| 
									
										
										
										
											2014-08-20 20:30:45 +10:00
										 |  |  | 		unsigned int i; | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		/* bugger, need to re-calculate the normals for the new edge faces.
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		 * This could be done in many ways, but probably the quickest way | 
					
						
							|  |  |  | 		 * is to calculate the average normals for side faces only. | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		 * Then blend them with the normals of the edge verts. | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 		 * | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		 * at the moment its easiest to allocate an entire array for every vertex, | 
					
						
							|  |  |  | 		 * even though we only need edge verts - campbell | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		 */ | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #define SOLIDIFY_SIDE_NORMALS
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef SOLIDIFY_SIDE_NORMALS
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		/* Note that, due to the code setting cd_dirty_vert a few lines above,
 | 
					
						
							|  |  |  | 		 * do_side_normals is always false. - Sybren */ | 
					
						
							|  |  |  | 		const bool do_side_normals = !(result->runtime.cd_dirty_vert & CD_MASK_NORMAL); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		/* annoying to allocate these since we only need the edge verts, */ | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  | 		float (*edge_vert_nos)[3] = do_side_normals ? MEM_calloc_arrayN(numVerts, 3 * sizeof(float), __func__) : NULL; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		float nor[3]; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		const unsigned char crease_rim = smd->crease_rim * 255.0f; | 
					
						
							|  |  |  | 		const unsigned char crease_outer = smd->crease_outer * 255.0f; | 
					
						
							|  |  |  | 		const unsigned char crease_inner = smd->crease_inner * 255.0f; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 		int *origindex_edge; | 
					
						
							|  |  |  | 		int *orig_ed; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 		unsigned int j; | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-02-26 14:32:53 +00:00
										 |  |  | 		if (crease_rim || crease_outer || crease_inner) { | 
					
						
							|  |  |  | 			result->cd_flag |= ME_CDFLAG_EDGE_CREASE; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		/* add faces & edges */ | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 		origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); | 
					
						
							| 
									
										
										
										
											2018-08-07 12:58:08 +10:00
										 |  |  | 		BLI_assert((numEdges == 0) || (origindex_edge != NULL)); | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 		ed = &medge[(numEdges * stride) + newEdges];  /* start after copied edges */ | 
					
						
							|  |  |  | 		orig_ed = &origindex_edge[(numEdges * stride) + newEdges]; | 
					
						
							|  |  |  | 		for (i = 0; i < rimVerts; i++, ed++, orig_ed++) { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			ed->v1 = new_vert_arr[i]; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			ed->v2 = (do_shell ? new_vert_arr[i] : i) + numVerts; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			ed->flag |= ME_EDGEDRAW; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 			*orig_ed = ORIGINDEX_NONE; | 
					
						
							| 
									
										
										
										
											2011-09-22 16:57:16 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 			if (crease_rim) { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 				ed->crease = crease_rim; | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* faces */ | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 		mp = mpoly + (numFaces * stride); | 
					
						
							|  |  |  | 		ml = mloop + (numLoops * stride); | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 		j = 0; | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 		for (i = 0; i < newFaces; i++, mp++) { | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 			unsigned int eidx = new_edge_arr[i]; | 
					
						
							|  |  |  | 			unsigned int fidx = edge_users[eidx]; | 
					
						
							|  |  |  | 			int k1, k2; | 
					
						
							|  |  |  | 			bool flip; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 			if (fidx >= numFaces) { | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 				fidx -= numFaces; | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 				flip = true; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 				flip = false; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 			ed = medge + eidx; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* copy most of the face settings */ | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 			CustomData_copy_data(&mesh->pdata, &result->pdata, (int)fidx, (int)((numFaces * stride) + i), 1); | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			mp->loopstart = (int)(j + (numLoops * stride)); | 
					
						
							| 
									
										
										
										
											2011-06-01 19:30:19 +00:00
										 |  |  | 			mp->flag = mpoly[fidx].flag; | 
					
						
							| 
									
										
										
										
											2012-01-17 13:18:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-17 13:26:59 +00:00
										 |  |  | 			/* notice we use 'mp->totloop' which is later overwritten,
 | 
					
						
							| 
									
										
										
										
											2018-09-03 16:49:08 +02:00
										 |  |  | 			 * we could lookup the original face but there's no point since this is a copy | 
					
						
							| 
									
										
										
										
											2012-01-17 13:26:59 +00:00
										 |  |  | 			 * and will have the same value, just take care when changing order of assignment */ | 
					
						
							| 
									
										
										
										
											2012-09-25 01:21:21 +00:00
										 |  |  | 			k1 = mpoly[fidx].loopstart + (((edge_order[eidx] - 1) + mp->totloop) % mp->totloop);  /* prev loop */ | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 			k2 = mpoly[fidx].loopstart +   (edge_order[eidx]); | 
					
						
							| 
									
										
										
										
											2012-01-17 13:26:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			mp->totloop = 4; | 
					
						
							| 
									
										
										
										
											2012-01-17 13:18:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 			CustomData_copy_data(&mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 0), 1); | 
					
						
							|  |  |  | 			CustomData_copy_data(&mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 1), 1); | 
					
						
							|  |  |  | 			CustomData_copy_data(&mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 2), 1); | 
					
						
							|  |  |  | 			CustomData_copy_data(&mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 3), 1); | 
					
						
							| 
									
										
										
										
											2012-01-17 13:18:23 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-03-20 22:56:28 +11:00
										 |  |  | 			if (flip == false) { | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 				ml[j].v = ed->v1; | 
					
						
							|  |  |  | 				ml[j++].e = eidx; | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 				ml[j].v = ed->v2; | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 				ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges; | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts; | 
					
						
							|  |  |  | 				ml[j++].e = (do_shell ? eidx : i) + numEdges; | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts; | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 				ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							| 
									
										
										
										
											2012-01-17 13:18:23 +00:00
										 |  |  | 				ml[j].v = ed->v2; | 
					
						
							|  |  |  | 				ml[j++].e = eidx; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				ml[j].v = ed->v1; | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 				ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges; | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts; | 
					
						
							|  |  |  | 				ml[j++].e = (do_shell ? eidx : i) + numEdges; | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts; | 
					
						
							| 
									
										
										
										
											2015-02-26 18:44:45 +11:00
										 |  |  | 				ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-25 06:54:01 +00:00
										 |  |  | 			origindex_edge[ml[j - 3].e] = ORIGINDEX_NONE; | 
					
						
							|  |  |  | 			origindex_edge[ml[j - 1].e] = ORIGINDEX_NONE; | 
					
						
							| 
									
										
										
										
											2012-02-11 21:39:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* use the next material index if option enabled */ | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 			if (mat_ofs_rim) { | 
					
						
							| 
									
										
										
										
											2012-02-11 21:39:09 +00:00
										 |  |  | 				mp->mat_nr += mat_ofs_rim; | 
					
						
							|  |  |  | 				CLAMP(mp->mat_nr, 0, mat_nr_max); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 			if (crease_outer) { | 
					
						
							| 
									
										
										
										
											2011-03-06 22:10:33 +00:00
										 |  |  | 				/* crease += crease_outer; without wrapping */ | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				char *cr = &(ed->crease); | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  | 				int tcr = *cr + crease_outer; | 
					
						
							|  |  |  | 				*cr = tcr > 255 ? 255 : tcr; | 
					
						
							| 
									
										
										
										
											2011-03-06 22:10:33 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-03-24 06:24:53 +00:00
										 |  |  | 			if (crease_inner) { | 
					
						
							| 
									
										
										
										
											2011-03-06 22:10:33 +00:00
										 |  |  | 				/* crease += crease_inner; without wrapping */ | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 				char *cr = &(medge[numEdges + (do_shell ? eidx : i)].crease); | 
					
						
							| 
									
										
										
										
											2012-05-03 21:35:04 +00:00
										 |  |  | 				int tcr = *cr + crease_inner; | 
					
						
							|  |  |  | 				*cr = tcr > 255 ? 255 : tcr; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #ifdef SOLIDIFY_SIDE_NORMALS
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 			if (do_side_normals) { | 
					
						
							|  |  |  | 				normal_quad_v3(nor, | 
					
						
							|  |  |  | 				               mvert[ml[j - 4].v].co, | 
					
						
							|  |  |  | 				               mvert[ml[j - 3].v].co, | 
					
						
							|  |  |  | 				               mvert[ml[j - 2].v].co, | 
					
						
							|  |  |  | 				               mvert[ml[j - 1].v].co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				add_v3_v3(edge_vert_nos[ed->v1], nor); | 
					
						
							|  |  |  | 				add_v3_v3(edge_vert_nos[ed->v2], nor); | 
					
						
							| 
									
										
										
										
											2012-02-26 18:12:01 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #ifdef SOLIDIFY_SIDE_NORMALS
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 		if (do_side_normals) { | 
					
						
							| 
									
										
										
										
											2018-05-03 19:48:28 +02:00
										 |  |  | 			const MEdge *ed_orig = medge; | 
					
						
							| 
									
										
										
										
											2014-08-15 17:26:39 +10:00
										 |  |  | 			ed = medge + (numEdges * stride); | 
					
						
							| 
									
										
										
										
											2018-05-03 19:48:28 +02:00
										 |  |  | 			for (i = 0; i < rimVerts; i++, ed++, ed_orig++) { | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 				float nor_cpy[3]; | 
					
						
							|  |  |  | 				short *nor_short; | 
					
						
							|  |  |  | 				int k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* note, only the first vertex (lower half of the index) is calculated */ | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 				BLI_assert(ed->v1 < numVerts); | 
					
						
							| 
									
										
										
										
											2018-05-03 19:48:28 +02:00
										 |  |  | 				normalize_v3_v3(nor_cpy, edge_vert_nos[ed_orig->v1]); | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ | 
					
						
							|  |  |  | 					nor_short = mvert[*(&ed->v1 + k)].no; | 
					
						
							|  |  |  | 					normal_short_to_float_v3(nor, nor_short); | 
					
						
							|  |  |  | 					add_v3_v3(nor, nor_cpy); | 
					
						
							|  |  |  | 					normalize_v3(nor); | 
					
						
							|  |  |  | 					normal_float_to_short_v3(nor_short, nor); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 			MEM_freeN(edge_vert_nos); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:20:24 +00:00
										 |  |  | 		MEM_freeN(new_vert_arr); | 
					
						
							|  |  |  | 		MEM_freeN(new_edge_arr); | 
					
						
							| 
									
										
										
										
											2013-06-12 06:51:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 		MEM_freeN(edge_users); | 
					
						
							|  |  |  | 		MEM_freeN(edge_order); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 	if (old_vert_arr) | 
					
						
							|  |  |  | 		MEM_freeN(old_vert_arr); | 
					
						
							| 
									
										
										
										
											2012-05-26 09:39:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 09:35:02 +00:00
										 |  |  | 	if (face_nors) | 
					
						
							|  |  |  | 		MEM_freeN(face_nors); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-12-05 01:02:41 +00:00
										 |  |  | 	if (numFaces == 0 && numEdges != 0) { | 
					
						
							|  |  |  | 		modifier_setError(md, "Faces needed for useful output"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-03 00:25:01 +00:00
										 |  |  | 	return result; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #undef SOLIDIFY_SIDE_NORMALS
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | static bool dependsOnNormals(ModifierData *UNUSED(md)) | 
					
						
							| 
									
										
										
										
											2013-06-02 04:09:29 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-12 06:06:19 +00:00
										 |  |  | 	/* even when we calculate our own normals,
 | 
					
						
							|  |  |  | 	 * the vertex normals are used as a fallback */ | 
					
						
							|  |  |  | 	return true; | 
					
						
							| 
									
										
										
										
											2013-06-02 04:09:29 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | ModifierTypeInfo modifierType_Solidify = { | 
					
						
							|  |  |  | 	/* name */              "Solidify", | 
					
						
							|  |  |  | 	/* structName */        "SolidifyModifierData", | 
					
						
							|  |  |  | 	/* structSize */        sizeof(SolidifyModifierData), | 
					
						
							|  |  |  | 	/* 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 15:04:10 +02:00
										 |  |  | 	/* copyData */          modifier_copyData_generic, | 
					
						
							| 
									
										
										
										
											2018-04-18 15:45:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* deformVerts_DM */    NULL, | 
					
						
							|  |  |  | 	/* deformMatrices_DM */ NULL, | 
					
						
							|  |  |  | 	/* deformVertsEM_DM */  NULL, | 
					
						
							|  |  |  | 	/* deformMatricesEM_DM*/NULL, | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	/* applyModifier_DM */  NULL, | 
					
						
							| 
									
										
										
										
											2018-04-18 15:45:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-20 15:48:01 +00:00
										 |  |  | 	/* deformVerts */       NULL, | 
					
						
							|  |  |  | 	/* deformMatrices */    NULL, | 
					
						
							|  |  |  | 	/* deformVertsEM */     NULL, | 
					
						
							|  |  |  | 	/* deformMatricesEM */  NULL, | 
					
						
							| 
									
										
										
										
											2018-05-02 15:08:54 +02:00
										 |  |  | 	/* applyModifier */     applyModifier, | 
					
						
							| 
									
										
										
										
											2018-04-18 15:45:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 	/* initData */          initData, | 
					
						
							| 
									
										
										
										
											2010-06-03 22:08:14 +00:00
										 |  |  | 	/* requiredDataMask */  requiredDataMask, | 
					
						
							| 
									
										
										
										
											2011-02-20 15:48:01 +00:00
										 |  |  | 	/* freeData */          NULL, | 
					
						
							|  |  |  | 	/* isDisabled */        NULL, | 
					
						
							| 
									
										
											  
											
												Depsgraph: New dependency graph integration commit
This commit integrates the work done so far on the new dependency graph system,
where goal was to replace legacy depsgraph with the new one, supporting loads of
neat features like:
- More granular dependency relation nature, which solves issues with fake cycles
  in the dependencies.
- Move towards all-animatable, by better integration of drivers into the system.
- Lay down some basis for upcoming copy-on-write, overrides and so on.
The new system is living side-by-side with the previous one and disabled by
default, so nothing will become suddenly broken. The way to enable new depsgraph
is to pass `--new-depsgraph` command line argument.
It's a bit early to consider the system production-ready, there are some TODOs
and issues were discovered during the merge period, they'll be addressed ASAP.
But it's important to merge, because it's the only way to attract artists to
really start testing this system.
There are number of assorted documents related on the design of the new system:
* http://wiki.blender.org/index.php/User:Aligorith/GSoC2013_Depsgraph#Design_Documents
* http://wiki.blender.org/index.php/User:Nazg-gul/DependencyGraph
There are also some user-related information online:
* http://code.blender.org/2015/02/blender-dependency-graph-branch-for-users/
* http://code.blender.org/2015/03/more-dependency-graph-tricks/
Kudos to everyone who was involved into the project:
- Joshua "Aligorith" Leung -- design specification, initial code
- Lukas "lukas_t" Toenne -- integrating code into blender, with further fixes
- Sergey "Sergey" "Sharybin" -- some mocking around, trying to wrap up the
  project and so
- Bassam "slikdigit" Kurdali -- stressing the new system, reporting all the
  issues and recording/writing documentation.
- Everyone else who i forgot to mention here :)
											
										 
											2015-05-12 15:05:57 +05:00
										 |  |  | 	/* updateDepsgraph */   NULL, | 
					
						
							| 
									
										
										
										
											2011-02-20 15:48:01 +00:00
										 |  |  | 	/* dependsOnTime */     NULL, | 
					
						
							| 
									
										
										
										
											2013-06-02 04:09:29 +00:00
										 |  |  | 	/* dependsOnNormals */  dependsOnNormals, | 
					
						
							| 
									
										
										
										
											2011-02-20 15:48:01 +00:00
										 |  |  | 	/* foreachObjectLink */ NULL, | 
					
						
							| 
									
										
										
										
											2011-08-12 18:11:22 +00:00
										 |  |  | 	/* foreachIDLink */     NULL, | 
					
						
							|  |  |  | 	/* foreachTexLink */    NULL, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | }; |