| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2020-05-09 17:14:35 +10:00
										 |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2011-10-23 17:52:20 +00:00
										 |  |  |  * 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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup modifiers | 
					
						
							| 
									
										
										
										
											2011-02-25 13:57:17 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-25 11:56:24 +01:00
										 |  |  | #include "BLI_utildefines.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_edgehash.h"
 | 
					
						
							|  |  |  | #include "BLI_kdtree.h"
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							|  |  |  | #include "BLI_rand.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | #include "BLT_translation.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-01 09:38:00 -05:00
										 |  |  | #include "DNA_defaults.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "DNA_mesh_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "DNA_meshdata_types.h"
 | 
					
						
							| 
									
										
										
										
											2012-04-30 08:24:44 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-19 09:33:03 +01:00
										 |  |  | #include "DNA_scene_types.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | #include "DNA_screen_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-27 05:39:55 +00:00
										 |  |  | #include "BKE_deform.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #include "BKE_lattice.h"
 | 
					
						
							| 
									
										
										
										
											2020-02-10 12:58:59 +01:00
										 |  |  | #include "BKE_lib_id.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | #include "BKE_mesh.h"
 | 
					
						
							|  |  |  | #include "BKE_modifier.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | #include "BKE_particle.h"
 | 
					
						
							| 
									
										
										
										
											2010-06-27 05:39:55 +00:00
										 |  |  | #include "BKE_scene.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | #include "BKE_screen.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "UI_interface.h"
 | 
					
						
							|  |  |  | #include "UI_resources.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-23 17:25:44 +02:00
										 |  |  | #include "BLO_read_write.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-07 19:18:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-22 15:03:42 +02:00
										 |  |  | #include "DEG_depsgraph_query.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-12 22:33:43 +00:00
										 |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 09:06:34 +10:00
										 |  |  | #include "MOD_modifiertypes.h"
 | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | #include "MOD_ui_common.h"
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static void initData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |   ExplodeModifierData *emd = (ExplodeModifierData *)md; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-01 09:38:00 -05:00
										 |  |  |   BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(emd, modifier)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   MEMCPY_STRUCT_AFTER(emd, DNA_struct_default_get(ExplodeModifierData), modifier); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | static void freeData(ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |   ExplodeModifierData *emd = (ExplodeModifierData *)md; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:04:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 14:21:02 +02:00
										 |  |  |   MEM_SAFE_FREE(emd->facepa); | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-07-04 12:45:30 +02:00
										 |  |  | static void copyData(const ModifierData *md, ModifierData *target, const int flag) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-22 04:35:52 +11:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2019-04-17 08:24:14 +02:00
										 |  |  |   const ExplodeModifierData *emd = (const ExplodeModifierData *)md; | 
					
						
							| 
									
										
										
										
											2013-12-22 04:35:52 +11:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |   ExplodeModifierData *temd = (ExplodeModifierData *)target; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-08 10:14:02 +02:00
										 |  |  |   BKE_modifier_copydata_generic(md, target, flag); | 
					
						
							| 
									
										
										
										
											2013-12-22 04:35:52 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-05 10:29:10 +00:00
										 |  |  |   temd->facepa = NULL; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2013-06-02 03:59:19 +00:00
										 |  |  | static bool dependsOnTime(ModifierData *UNUSED(md)) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-06-02 03:59:19 +00:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
											
												Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
											
										 
											2019-03-07 11:13:40 +01:00
										 |  |  | static void requiredDataMask(Object *UNUSED(ob), | 
					
						
							|  |  |  |                              ModifierData *md, | 
					
						
							|  |  |  |                              CustomData_MeshMasks *r_cddata_masks) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-05-06 13:38:33 +00:00
										 |  |  |   ExplodeModifierData *emd = (ExplodeModifierData *)md; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												Refactor CDData masks, to have one mask per mesh elem type.
We already have different storages for cddata of verts, edges etc.,
'simply' do the same for the mask flags we use all around Blender code
to request some data, or limit some operation to some layers, etc.
Reason we need this is that some cddata types (like Normals) are
actually shared between verts/polys/loops, and we don’t want to generate
clnors everytime we request vnors!
As a side note, this also does final fix to T59338, which was the
trigger for this patch (need to request computed loop normals for
another mesh than evaluated one).
Reviewers: brecht, campbellbarton, sergey
Differential Revision: https://developer.blender.org/D4407
											
										 
											2019-03-07 11:13:40 +01:00
										 |  |  |   if (emd->vgroup) { | 
					
						
							|  |  |  |     r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-12 08:04:56 +02:00
										 |  |  | static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Mesh *mesh) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   ParticleSystem *psys = psmd->psys; | 
					
						
							|  |  |  |   MFace *fa = NULL, *mface = NULL; | 
					
						
							|  |  |  |   MVert *mvert = NULL; | 
					
						
							|  |  |  |   ParticleData *pa; | 
					
						
							| 
									
										
										
										
											2019-03-20 00:46:33 +11:00
										 |  |  |   KDTree_3d *tree; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   RNG *rng; | 
					
						
							|  |  |  |   float center[3], co[3]; | 
					
						
							|  |  |  |   int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0; | 
					
						
							|  |  |  |   int i, p, v1, v2, v3, v4 = 0; | 
					
						
							| 
									
										
										
										
											2020-02-18 17:03:20 +01:00
										 |  |  |   const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   mvert = mesh->mvert; | 
					
						
							|  |  |  |   mface = mesh->mface; | 
					
						
							|  |  |  |   totvert = mesh->totvert; | 
					
						
							|  |  |  |   totface = mesh->totface; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   totpart = psmd->psys->totpart; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   rng = BLI_rng_new_srandom(psys->seed); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   if (emd->facepa) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     MEM_freeN(emd->facepa); | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  |   facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  |   vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa"); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* initialize all faces & verts to no particle */ | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   for (i = 0; i < totface; i++) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     facepa[i] = totpart; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   } | 
					
						
							|  |  |  |   for (i = 0; i < totvert; i++) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     vertpa[i] = totpart; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* set protected verts */ | 
					
						
							|  |  |  |   if (emd->vgroup) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (dvert) { | 
					
						
							|  |  |  |       const int defgrp_index = emd->vgroup - 1; | 
					
						
							|  |  |  |       for (i = 0; i < totvert; i++, dvert++) { | 
					
						
							|  |  |  |         float val = BLI_rng_get_float(rng); | 
					
						
							|  |  |  |         val = (1.0f - emd->protect) * val + emd->protect * 0.5f; | 
					
						
							| 
									
										
										
										
											2020-03-06 12:50:56 +11:00
										 |  |  |         const float weight = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dvert, defgrp_index) : | 
					
						
							|  |  |  |                                              BKE_defvert_find_weight(dvert, defgrp_index); | 
					
						
							| 
									
										
										
										
											2020-02-18 17:03:20 +01:00
										 |  |  |         if (val < weight) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |           vertpa[i] = -1; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* make tree of emitter locations */ | 
					
						
							| 
									
										
										
										
											2019-03-20 00:46:33 +11:00
										 |  |  |   tree = BLI_kdtree_3d_new(totpart); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (p = 0, pa = psys->particles; p < totpart; p++, pa++) { | 
					
						
							| 
									
										
											  
											
												Remove Blender Internal and legacy viewport from Blender 2.8.
Brecht authored this commit, but he gave me the honours to actually
do it. Here it goes; Blender Internal. Bye bye, you did great!
* Point density, voxel data, ocean, environment map textures were removed,
  as these only worked within BI rendering. Note that the ocean modifier
  and the Cycles point density shader node continue to work.
* Dynamic paint using material shading was removed, as this only worked
  with BI. If we ever wanted to support this again probably it should go
  through the baking API.
* GPU shader export through the Python API was removed. This only worked
  for the old BI GLSL shaders, which no longer exists. Doing something
  similar for Eevee would be significantly more complicated because it
  uses a lot of multiplass rendering and logic outside the shader, it's
  probably impractical.
* Collada material import / export code is mostly gone, as it only worked
  for BI materials. We need to add Cycles / Eevee material support at some
  point.
* The mesh noise operator was removed since it only worked with BI
  material texture slots. A displacement modifier can be used instead.
* The delete texture paint slot operator was removed since it only worked
  for BI material texture slots. Could be added back with node support.
* Not all legacy viewport features are supported in the new viewport, but
  their code was removed. If we need to bring anything back we can look at
  older git revisions.
* There is some legacy viewport code that I could not remove yet, and some
  that I probably missed.
* Shader node execution code was left mostly intact, even though it is not
  used anywhere now. We may eventually use this to replace the texture
  nodes with Cycles / Eevee shader nodes.
* The Cycles Bake panel now includes settings for baking multires normal
  and displacement maps. The underlying code needs to be merged properly,
  and we plan to add back support for multires AO baking and add support
  to Cycles baking for features like vertex color, displacement, and other
  missing baking features.
* This commit removes DNA and the Python API for BI material, lamp, world
  and scene settings. This breaks a lot of addons.
* There is more DNA that can be removed or renamed, where Cycles or Eevee
  are reusing some old BI properties but the names are not really correct
  anymore.
* Texture slots for materials, lamps and world were removed. They remain
  for brushes, particles and freestyle linestyles.
* 'BLENDER_RENDER' remains in the COMPAT_ENGINES of UI panels. Cycles and
  other renderers use this to find all panels to show, minus a few panels
  that they have their own replacement for.
											
										 
											2018-04-19 17:34:44 +02:00
										 |  |  |     psys_particle_on_emitter(psmd, | 
					
						
							|  |  |  |                              psys->part->from, | 
					
						
							|  |  |  |                              pa->num, | 
					
						
							|  |  |  |                              pa->num_dmcache, | 
					
						
							|  |  |  |                              pa->fuv, | 
					
						
							|  |  |  |                              pa->foffset, | 
					
						
							|  |  |  |                              co, | 
					
						
							|  |  |  |                              NULL, | 
					
						
							|  |  |  |                              NULL, | 
					
						
							|  |  |  |                              NULL, | 
					
						
							|  |  |  |                              NULL); | 
					
						
							| 
									
										
										
										
											2019-03-20 00:46:33 +11:00
										 |  |  |     BLI_kdtree_3d_insert(tree, p, co); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-03-20 00:46:33 +11:00
										 |  |  |   BLI_kdtree_3d_balance(tree); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* set face-particle-indexes to nearest particle to face center */ | 
					
						
							|  |  |  |   for (i = 0, fa = mface; i < totface; i++, fa++) { | 
					
						
							|  |  |  |     add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co); | 
					
						
							|  |  |  |     add_v3_v3(center, mvert[fa->v3].co); | 
					
						
							|  |  |  |     if (fa->v4) { | 
					
						
							|  |  |  |       add_v3_v3(center, mvert[fa->v4].co); | 
					
						
							|  |  |  |       mul_v3_fl(center, 0.25); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     else { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       mul_v3_fl(center, 1.0f / 3.0f); | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-20 00:46:33 +11:00
										 |  |  |     p = BLI_kdtree_3d_find_nearest(tree, center, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     v1 = vertpa[fa->v1]; | 
					
						
							|  |  |  |     v2 = vertpa[fa->v2]; | 
					
						
							|  |  |  |     v3 = vertpa[fa->v3]; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (fa->v4) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       v4 = vertpa[fa->v4]; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (v1 >= 0 && v2 >= 0 && v3 >= 0 && (fa->v4 == 0 || v4 >= 0)) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       facepa[i] = p; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (v1 >= 0) { | 
					
						
							|  |  |  |       vertpa[fa->v1] = p; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (v2 >= 0) { | 
					
						
							|  |  |  |       vertpa[fa->v2] = p; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (v3 >= 0) { | 
					
						
							|  |  |  |       vertpa[fa->v3] = p; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (fa->v4 && v4 >= 0) { | 
					
						
							|  |  |  |       vertpa[fa->v4] = p; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   if (vertpa) { | 
					
						
							|  |  |  |     MEM_freeN(vertpa); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-03-20 00:46:33 +11:00
										 |  |  |   BLI_kdtree_3d_free(tree); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   BLI_rng_free(rng); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-19 13:32:36 +10:00
										 |  |  | static int edgecut_get(EdgeHash *edgehash, uint v1, uint v2) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-19 12:05:58 +10:00
										 |  |  |   return POINTER_AS_INT(BLI_edgehash_lookup(edgehash, v1, v2)); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const short add_faces[24] = { | 
					
						
							|  |  |  |     0, 0, 0, 2, 0, 1, 2, 2, 0, 2, 1, 2, 2, 2, 2, 3, 0, 0, 0, 1, 0, 1, 1, 2, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df = &split->mface[cur]; | 
					
						
							|  |  |  |   CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   *df = *mf; | 
					
						
							|  |  |  |   return df; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SET_VERTS(a, b, c, d) \
 | 
					
						
							|  |  |  |   { \ | 
					
						
							|  |  |  |     v[0] = mf->v##a; \ | 
					
						
							|  |  |  |     uv[0] = a - 1; \ | 
					
						
							|  |  |  |     v[1] = mf->v##b; \ | 
					
						
							|  |  |  |     uv[1] = b - 1; \ | 
					
						
							|  |  |  |     v[2] = mf->v##c; \ | 
					
						
							|  |  |  |     uv[2] = c - 1; \ | 
					
						
							|  |  |  |     v[3] = mf->v##d; \ | 
					
						
							|  |  |  |     uv[3] = d - 1; \ | 
					
						
							|  |  |  |   } \ | 
					
						
							|  |  |  |   (void)0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GET_ES(v1, v2) edgecut_get(eh, v1, v2)
 | 
					
						
							|  |  |  | #define INT_UV(uvf, c0, c1) mid_v2_v2v2(uvf, mf->uv[c0], mf->uv[c1])
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_faces_3_6_9_12(Mesh *mesh, | 
					
						
							|  |  |  |                                  Mesh *split, | 
					
						
							|  |  |  |                                  MFace *mf, | 
					
						
							|  |  |  |                                  int *facepa, | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  |                                  const int *vertpa, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                                  int i, | 
					
						
							|  |  |  |                                  EdgeHash *eh, | 
					
						
							|  |  |  |                                  int cur, | 
					
						
							|  |  |  |                                  int v1, | 
					
						
							|  |  |  |                                  int v2, | 
					
						
							|  |  |  |                                  int v3, | 
					
						
							|  |  |  |                                  int v4) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df1 = get_dface(mesh, split, cur, i, mf); | 
					
						
							|  |  |  |   MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | 
					
						
							|  |  |  |   MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur] = vertpa[v1]; | 
					
						
							|  |  |  |   df1->v1 = v1; | 
					
						
							|  |  |  |   df1->v2 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df1->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df1->v4 = v3; | 
					
						
							|  |  |  |   df1->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 1] = vertpa[v2]; | 
					
						
							|  |  |  |   df2->v1 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df2->v2 = v2; | 
					
						
							|  |  |  |   df2->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df2->v4 = 0; | 
					
						
							|  |  |  |   df2->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 2] = vertpa[v1]; | 
					
						
							|  |  |  |   df3->v1 = v1; | 
					
						
							|  |  |  |   df3->v2 = v3; | 
					
						
							|  |  |  |   df3->v3 = v4; | 
					
						
							|  |  |  |   df3->v4 = 0; | 
					
						
							|  |  |  |   df3->flag &= ~ME_FACE_SEL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_uvs_3_6_9_12( | 
					
						
							|  |  |  |     Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   MTFace *mf, *df1, *df2, *df3; | 
					
						
							|  |  |  |   int l; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (l = 0; l < numlayer; l++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     df1 = mf + cur; | 
					
						
							|  |  |  |     df2 = df1 + 1; | 
					
						
							|  |  |  |     df3 = df1 + 2; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf += i; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df1->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     INT_UV(df1->uv[1], c0, c1); | 
					
						
							|  |  |  |     INT_UV(df1->uv[2], c1, c2); | 
					
						
							|  |  |  |     copy_v2_v2(df1->uv[3], mf->uv[c2]); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c1); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[1], mf->uv[c1]); | 
					
						
							|  |  |  |     INT_UV(df2->uv[2], c1, c2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df3->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     copy_v2_v2(df3->uv[1], mf->uv[c2]); | 
					
						
							|  |  |  |     copy_v2_v2(df3->uv[2], mf->uv[c3]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_faces_5_10(Mesh *mesh, | 
					
						
							|  |  |  |                              Mesh *split, | 
					
						
							|  |  |  |                              MFace *mf, | 
					
						
							|  |  |  |                              int *facepa, | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  |                              const int *vertpa, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                              int i, | 
					
						
							|  |  |  |                              EdgeHash *eh, | 
					
						
							|  |  |  |                              int cur, | 
					
						
							|  |  |  |                              int v1, | 
					
						
							|  |  |  |                              int v2, | 
					
						
							|  |  |  |                              int v3, | 
					
						
							|  |  |  |                              int v4) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df1 = get_dface(mesh, split, cur, i, mf); | 
					
						
							|  |  |  |   MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur] = vertpa[v1]; | 
					
						
							|  |  |  |   df1->v1 = v1; | 
					
						
							|  |  |  |   df1->v2 = v2; | 
					
						
							|  |  |  |   df1->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df1->v4 = GET_ES(v1, v4); | 
					
						
							|  |  |  |   df1->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 1] = vertpa[v3]; | 
					
						
							|  |  |  |   df2->v1 = GET_ES(v1, v4); | 
					
						
							|  |  |  |   df2->v2 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df2->v3 = v3; | 
					
						
							|  |  |  |   df2->v4 = v4; | 
					
						
							|  |  |  |   df2->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_uvs_5_10( | 
					
						
							|  |  |  |     Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   MTFace *mf, *df1, *df2; | 
					
						
							|  |  |  |   int l; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (l = 0; l < numlayer; l++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     df1 = mf + cur; | 
					
						
							|  |  |  |     df2 = df1 + 1; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf += i; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df1->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     copy_v2_v2(df1->uv[1], mf->uv[c1]); | 
					
						
							|  |  |  |     INT_UV(df1->uv[2], c1, c2); | 
					
						
							|  |  |  |     INT_UV(df1->uv[3], c0, c3); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c3); | 
					
						
							|  |  |  |     INT_UV(df2->uv[1], c1, c2); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[2], mf->uv[c2]); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[3], mf->uv[c3]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_faces_15(Mesh *mesh, | 
					
						
							|  |  |  |                            Mesh *split, | 
					
						
							|  |  |  |                            MFace *mf, | 
					
						
							|  |  |  |                            int *facepa, | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  |                            const int *vertpa, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                            int i, | 
					
						
							|  |  |  |                            EdgeHash *eh, | 
					
						
							|  |  |  |                            int cur, | 
					
						
							|  |  |  |                            int v1, | 
					
						
							|  |  |  |                            int v2, | 
					
						
							|  |  |  |                            int v3, | 
					
						
							|  |  |  |                            int v4) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df1 = get_dface(mesh, split, cur, i, mf); | 
					
						
							|  |  |  |   MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | 
					
						
							|  |  |  |   MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | 
					
						
							|  |  |  |   MFace *df4 = get_dface(mesh, split, cur + 3, i, mf); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur] = vertpa[v1]; | 
					
						
							|  |  |  |   df1->v1 = v1; | 
					
						
							|  |  |  |   df1->v2 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df1->v3 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df1->v4 = GET_ES(v1, v4); | 
					
						
							|  |  |  |   df1->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 1] = vertpa[v2]; | 
					
						
							|  |  |  |   df2->v1 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df2->v2 = v2; | 
					
						
							|  |  |  |   df2->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df2->v4 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df2->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 2] = vertpa[v3]; | 
					
						
							|  |  |  |   df3->v1 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df3->v2 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df3->v3 = v3; | 
					
						
							|  |  |  |   df3->v4 = GET_ES(v3, v4); | 
					
						
							|  |  |  |   df3->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 3] = vertpa[v4]; | 
					
						
							|  |  |  |   df4->v1 = GET_ES(v1, v4); | 
					
						
							|  |  |  |   df4->v2 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df4->v3 = GET_ES(v3, v4); | 
					
						
							|  |  |  |   df4->v4 = v4; | 
					
						
							|  |  |  |   df4->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_uvs_15( | 
					
						
							|  |  |  |     Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   MTFace *mf, *df1, *df2, *df3, *df4; | 
					
						
							|  |  |  |   int l; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (l = 0; l < numlayer; l++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     df1 = mf + cur; | 
					
						
							|  |  |  |     df2 = df1 + 1; | 
					
						
							|  |  |  |     df3 = df1 + 2; | 
					
						
							|  |  |  |     df4 = df1 + 3; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf += i; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df1->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     INT_UV(df1->uv[1], c0, c1); | 
					
						
							|  |  |  |     INT_UV(df1->uv[2], c0, c2); | 
					
						
							|  |  |  |     INT_UV(df1->uv[3], c0, c3); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c1); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[1], mf->uv[c1]); | 
					
						
							|  |  |  |     INT_UV(df2->uv[2], c1, c2); | 
					
						
							|  |  |  |     INT_UV(df2->uv[3], c0, c2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df3->uv[0], c0, c2); | 
					
						
							|  |  |  |     INT_UV(df3->uv[1], c1, c2); | 
					
						
							|  |  |  |     copy_v2_v2(df3->uv[2], mf->uv[c2]); | 
					
						
							|  |  |  |     INT_UV(df3->uv[3], c2, c3); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df4->uv[0], c0, c3); | 
					
						
							|  |  |  |     INT_UV(df4->uv[1], c0, c2); | 
					
						
							|  |  |  |     INT_UV(df4->uv[2], c2, c3); | 
					
						
							|  |  |  |     copy_v2_v2(df4->uv[3], mf->uv[c3]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_faces_7_11_13_14(Mesh *mesh, | 
					
						
							|  |  |  |                                    Mesh *split, | 
					
						
							|  |  |  |                                    MFace *mf, | 
					
						
							|  |  |  |                                    int *facepa, | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  |                                    const int *vertpa, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                                    int i, | 
					
						
							|  |  |  |                                    EdgeHash *eh, | 
					
						
							|  |  |  |                                    int cur, | 
					
						
							|  |  |  |                                    int v1, | 
					
						
							|  |  |  |                                    int v2, | 
					
						
							|  |  |  |                                    int v3, | 
					
						
							|  |  |  |                                    int v4) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df1 = get_dface(mesh, split, cur, i, mf); | 
					
						
							|  |  |  |   MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | 
					
						
							|  |  |  |   MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur] = vertpa[v1]; | 
					
						
							|  |  |  |   df1->v1 = v1; | 
					
						
							|  |  |  |   df1->v2 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df1->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df1->v4 = GET_ES(v1, v4); | 
					
						
							|  |  |  |   df1->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 1] = vertpa[v2]; | 
					
						
							|  |  |  |   df2->v1 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df2->v2 = v2; | 
					
						
							|  |  |  |   df2->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df2->v4 = 0; | 
					
						
							|  |  |  |   df2->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 2] = vertpa[v4]; | 
					
						
							|  |  |  |   df3->v1 = GET_ES(v1, v4); | 
					
						
							|  |  |  |   df3->v2 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df3->v3 = v3; | 
					
						
							|  |  |  |   df3->v4 = v4; | 
					
						
							|  |  |  |   df3->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_uvs_7_11_13_14( | 
					
						
							|  |  |  |     Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   MTFace *mf, *df1, *df2, *df3; | 
					
						
							|  |  |  |   int l; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (l = 0; l < numlayer; l++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     df1 = mf + cur; | 
					
						
							|  |  |  |     df2 = df1 + 1; | 
					
						
							|  |  |  |     df3 = df1 + 2; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf += i; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df1->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     INT_UV(df1->uv[1], c0, c1); | 
					
						
							|  |  |  |     INT_UV(df1->uv[2], c1, c2); | 
					
						
							|  |  |  |     INT_UV(df1->uv[3], c0, c3); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c1); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[1], mf->uv[c1]); | 
					
						
							|  |  |  |     INT_UV(df2->uv[2], c1, c2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df3->uv[0], c0, c3); | 
					
						
							|  |  |  |     INT_UV(df3->uv[1], c1, c2); | 
					
						
							|  |  |  |     copy_v2_v2(df3->uv[2], mf->uv[c2]); | 
					
						
							|  |  |  |     copy_v2_v2(df3->uv[3], mf->uv[c3]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_faces_19_21_22(Mesh *mesh, | 
					
						
							|  |  |  |                                  Mesh *split, | 
					
						
							|  |  |  |                                  MFace *mf, | 
					
						
							|  |  |  |                                  int *facepa, | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  |                                  const int *vertpa, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                                  int i, | 
					
						
							|  |  |  |                                  EdgeHash *eh, | 
					
						
							|  |  |  |                                  int cur, | 
					
						
							|  |  |  |                                  int v1, | 
					
						
							|  |  |  |                                  int v2, | 
					
						
							|  |  |  |                                  int v3) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df1 = get_dface(mesh, split, cur, i, mf); | 
					
						
							|  |  |  |   MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur] = vertpa[v1]; | 
					
						
							|  |  |  |   df1->v1 = v1; | 
					
						
							|  |  |  |   df1->v2 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df1->v3 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df1->v4 = 0; | 
					
						
							|  |  |  |   df1->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 1] = vertpa[v2]; | 
					
						
							|  |  |  |   df2->v1 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df2->v2 = v2; | 
					
						
							|  |  |  |   df2->v3 = v3; | 
					
						
							|  |  |  |   df2->v4 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df2->flag |= ME_FACE_SEL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_uvs_19_21_22( | 
					
						
							|  |  |  |     Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   MTFace *mf, *df1, *df2; | 
					
						
							|  |  |  |   int l; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (l = 0; l < numlayer; l++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     df1 = mf + cur; | 
					
						
							|  |  |  |     df2 = df1 + 1; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf += i; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df1->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     INT_UV(df1->uv[1], c0, c1); | 
					
						
							|  |  |  |     INT_UV(df1->uv[2], c0, c2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c1); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[1], mf->uv[c1]); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[2], mf->uv[c2]); | 
					
						
							|  |  |  |     INT_UV(df2->uv[3], c0, c2); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_faces_23(Mesh *mesh, | 
					
						
							|  |  |  |                            Mesh *split, | 
					
						
							|  |  |  |                            MFace *mf, | 
					
						
							|  |  |  |                            int *facepa, | 
					
						
							| 
									
										
										
										
											2020-07-13 11:27:09 +02:00
										 |  |  |                            const int *vertpa, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                            int i, | 
					
						
							|  |  |  |                            EdgeHash *eh, | 
					
						
							|  |  |  |                            int cur, | 
					
						
							|  |  |  |                            int v1, | 
					
						
							|  |  |  |                            int v2, | 
					
						
							|  |  |  |                            int v3) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *df1 = get_dface(mesh, split, cur, i, mf); | 
					
						
							|  |  |  |   MFace *df2 = get_dface(mesh, split, cur + 1, i, mf); | 
					
						
							|  |  |  |   MFace *df3 = get_dface(mesh, split, cur + 2, i, mf); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur] = vertpa[v1]; | 
					
						
							|  |  |  |   df1->v1 = v1; | 
					
						
							|  |  |  |   df1->v2 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df1->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df1->v4 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df1->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 1] = vertpa[v2]; | 
					
						
							|  |  |  |   df2->v1 = GET_ES(v1, v2); | 
					
						
							|  |  |  |   df2->v2 = v2; | 
					
						
							|  |  |  |   df2->v3 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df2->v4 = 0; | 
					
						
							|  |  |  |   df2->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   facepa[cur + 2] = vertpa[v3]; | 
					
						
							|  |  |  |   df3->v1 = GET_ES(v1, v3); | 
					
						
							|  |  |  |   df3->v2 = GET_ES(v2, v3); | 
					
						
							|  |  |  |   df3->v3 = v3; | 
					
						
							|  |  |  |   df3->v4 = 0; | 
					
						
							|  |  |  |   df3->flag &= ~ME_FACE_SEL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static void remap_uvs_23( | 
					
						
							|  |  |  |     Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							|  |  |  |   MTFace *mf, *df1, *df2; | 
					
						
							|  |  |  |   int l; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (l = 0; l < numlayer; l++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     df1 = mf + cur; | 
					
						
							|  |  |  |     df2 = df1 + 1; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf += i; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     copy_v2_v2(df1->uv[0], mf->uv[c0]); | 
					
						
							|  |  |  |     INT_UV(df1->uv[1], c0, c1); | 
					
						
							|  |  |  |     INT_UV(df1->uv[2], c1, c2); | 
					
						
							|  |  |  |     INT_UV(df1->uv[3], c0, c2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c1); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[1], mf->uv[c1]); | 
					
						
							|  |  |  |     INT_UV(df2->uv[2], c1, c2); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     INT_UV(df2->uv[0], c0, c2); | 
					
						
							|  |  |  |     INT_UV(df2->uv[1], c1, c2); | 
					
						
							|  |  |  |     copy_v2_v2(df2->uv[2], mf->uv[c2]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   Mesh *split_m; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   MFace *mf = NULL, *df1 = NULL; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   MFace *mface = mesh->mface; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   MVert *dupve, *mv; | 
					
						
							|  |  |  |   EdgeHash *edgehash; | 
					
						
							|  |  |  |   EdgeHashIterator *ehi; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   int totvert = mesh->totvert; | 
					
						
							|  |  |  |   int totface = mesh->totface; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  |   int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit"); | 
					
						
							|  |  |  |   int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2"); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   int *facepa = emd->facepa; | 
					
						
							|  |  |  |   int *fs, totesplit = 0, totfsplit = 0, curdupface = 0; | 
					
						
							|  |  |  |   int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ | 
					
						
							|  |  |  |       uv[4] = {0, 0, 0, 0};                           /* To quite gcc barking... */ | 
					
						
							|  |  |  |   int numlayer; | 
					
						
							| 
									
										
										
										
											2019-09-19 13:32:36 +10:00
										 |  |  |   uint ed_v1, ed_v2; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   edgehash = BLI_edgehash_new(__func__); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* recreate vertpa from facepa calculation */ | 
					
						
							|  |  |  |   for (i = 0, mf = mface; i < totface; i++, mf++) { | 
					
						
							|  |  |  |     vertpa[mf->v1] = facepa[i]; | 
					
						
							|  |  |  |     vertpa[mf->v2] = facepa[i]; | 
					
						
							|  |  |  |     vertpa[mf->v3] = facepa[i]; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (mf->v4) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       vertpa[mf->v4] = facepa[i]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* mark edges for splitting and how to split faces */ | 
					
						
							|  |  |  |   for (i = 0, mf = mface, fs = facesplit; i < totface; i++, mf++, fs++) { | 
					
						
							|  |  |  |     v1 = vertpa[mf->v1]; | 
					
						
							|  |  |  |     v2 = vertpa[mf->v2]; | 
					
						
							|  |  |  |     v3 = vertpa[mf->v3]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (v1 != v2) { | 
					
						
							|  |  |  |       BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL); | 
					
						
							|  |  |  |       (*fs) |= 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (v2 != v3) { | 
					
						
							|  |  |  |       BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL); | 
					
						
							|  |  |  |       (*fs) |= 2; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (mf->v4) { | 
					
						
							|  |  |  |       v4 = vertpa[mf->v4]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       if (v3 != v4) { | 
					
						
							|  |  |  |         BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL); | 
					
						
							|  |  |  |         (*fs) |= 4; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       if (v1 != v4) { | 
					
						
							|  |  |  |         BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL); | 
					
						
							|  |  |  |         (*fs) |= 8; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       /* mark center vertex as a fake edge split */ | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |       if (*fs == 15) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     else { | 
					
						
							|  |  |  |       (*fs) |= 16; /* mark face as tri */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       if (v1 != v3) { | 
					
						
							|  |  |  |         BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); | 
					
						
							|  |  |  |         (*fs) |= 4; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* count splits & create indexes for new verts */ | 
					
						
							|  |  |  |   ehi = BLI_edgehashIterator_new(edgehash); | 
					
						
							|  |  |  |   totesplit = totvert; | 
					
						
							|  |  |  |   for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | 
					
						
							| 
									
										
										
										
											2018-09-19 12:05:58 +10:00
										 |  |  |     BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totesplit)); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     totesplit++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   BLI_edgehashIterator_free(ehi); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* count new faces due to splitting */ | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |   for (i = 0, fs = facesplit; i < totface; i++, fs++) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     totfsplit += add_faces[*fs]; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   split_m = BKE_mesh_new_nomain_from_template(mesh, totesplit, 0, totface + totfsplit, 0, 0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   numlayer = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* copy new faces & verts (is it really this painful with custom data??) */ | 
					
						
							|  |  |  |   for (i = 0; i < totvert; i++) { | 
					
						
							|  |  |  |     MVert source; | 
					
						
							|  |  |  |     MVert *dest; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     source = mesh->mvert[i]; | 
					
						
							|  |  |  |     dest = &split_m->mvert[i]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     *dest = source; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* override original facepa (original pointer is saved in caller function) */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* BMESH_TODO, (totfsplit * 2) over allocation is used since the quads are
 | 
					
						
							|  |  |  |    * later interpreted as tri's, for this to work right I think we probably | 
					
						
							|  |  |  |    * have to stop using tessface - campbell */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-14 22:14:20 +01:00
										 |  |  |   facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa"); | 
					
						
							| 
									
										
										
										
											2019-05-01 07:40:07 +10:00
										 |  |  |   // memcpy(facepa, emd->facepa, totface*sizeof(int));
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   emd->facepa = facepa; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* create new verts */ | 
					
						
							|  |  |  |   ehi = BLI_edgehashIterator_new(edgehash); | 
					
						
							|  |  |  |   for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | 
					
						
							|  |  |  |     BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); | 
					
						
							| 
									
										
										
										
											2018-09-19 12:05:58 +10:00
										 |  |  |     esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mv = &split_m->mvert[ed_v2]; | 
					
						
							|  |  |  |     dupve = &split_m->mvert[esplit]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     *dupve = *mv; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mv = &split_m->mvert[ed_v1]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mid_v3_v3v3(dupve->co, dupve->co, mv->co); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   BLI_edgehashIterator_free(ehi); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* create new faces */ | 
					
						
							|  |  |  |   curdupface = 0;  //=totface;
 | 
					
						
							| 
									
										
										
										
											2019-05-01 07:40:07 +10:00
										 |  |  |   // curdupin=totesplit;
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (i = 0, fs = facesplit; i < totface; i++, fs++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = &mesh->mface[i]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     switch (*fs) { | 
					
						
							|  |  |  |       case 3: | 
					
						
							|  |  |  |       case 10: | 
					
						
							|  |  |  |       case 11: | 
					
						
							|  |  |  |       case 15: | 
					
						
							|  |  |  |         SET_VERTS(1, 2, 3, 4); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 5: | 
					
						
							|  |  |  |       case 6: | 
					
						
							|  |  |  |       case 7: | 
					
						
							|  |  |  |         SET_VERTS(2, 3, 4, 1); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 9: | 
					
						
							|  |  |  |       case 13: | 
					
						
							|  |  |  |         SET_VERTS(4, 1, 2, 3); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 12: | 
					
						
							|  |  |  |       case 14: | 
					
						
							|  |  |  |         SET_VERTS(3, 4, 1, 2); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 21: | 
					
						
							|  |  |  |       case 23: | 
					
						
							|  |  |  |         SET_VERTS(1, 2, 3, 4); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 19: | 
					
						
							|  |  |  |         SET_VERTS(2, 3, 1, 4); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case 22: | 
					
						
							|  |  |  |         SET_VERTS(3, 1, 2, 4); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     switch (*fs) { | 
					
						
							|  |  |  |       case 3: | 
					
						
							|  |  |  |       case 6: | 
					
						
							|  |  |  |       case 9: | 
					
						
							|  |  |  |       case 12: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         remap_faces_3_6_9_12( | 
					
						
							|  |  |  |             mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | 
					
						
							|  |  |  |         if (numlayer) { | 
					
						
							|  |  |  |           remap_uvs_3_6_9_12(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case 5: | 
					
						
							|  |  |  |       case 10: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         remap_faces_5_10( | 
					
						
							|  |  |  |             mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | 
					
						
							|  |  |  |         if (numlayer) { | 
					
						
							|  |  |  |           remap_uvs_5_10(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case 15: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         remap_faces_15( | 
					
						
							|  |  |  |             mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | 
					
						
							|  |  |  |         if (numlayer) { | 
					
						
							|  |  |  |           remap_uvs_15(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case 7: | 
					
						
							|  |  |  |       case 11: | 
					
						
							|  |  |  |       case 13: | 
					
						
							|  |  |  |       case 14: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         remap_faces_7_11_13_14( | 
					
						
							|  |  |  |             mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]); | 
					
						
							|  |  |  |         if (numlayer) { | 
					
						
							|  |  |  |           remap_uvs_7_11_13_14(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case 19: | 
					
						
							|  |  |  |       case 21: | 
					
						
							|  |  |  |       case 22: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         remap_faces_19_21_22( | 
					
						
							|  |  |  |             mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); | 
					
						
							|  |  |  |         if (numlayer) { | 
					
						
							|  |  |  |           remap_uvs_19_21_22(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case 23: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         remap_faces_23( | 
					
						
							|  |  |  |             mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]); | 
					
						
							|  |  |  |         if (numlayer) { | 
					
						
							|  |  |  |           remap_uvs_23(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |       case 0: | 
					
						
							|  |  |  |       case 16: | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         df1 = get_dface(mesh, split_m, curdupface, i, mf); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         facepa[curdupface] = vertpa[mf->v1]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         if (df1->v4) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |           df1->flag |= ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |         else { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |           df1->flag &= ~ME_FACE_SEL; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     curdupface += add_faces[*fs] + 1; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (i = 0; i < curdupface; i++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     mf = &split_m->mface[i]; | 
					
						
							|  |  |  |     test_index_face(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   BLI_edgehash_free(edgehash, NULL); | 
					
						
							|  |  |  |   MEM_freeN(facesplit); | 
					
						
							|  |  |  |   MEM_freeN(vertpa); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   BKE_mesh_calc_edges_tessface(split_m); | 
					
						
							|  |  |  |   BKE_mesh_convert_mfaces_to_mpolys(split_m); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   return split_m; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  | static Mesh *explodeMesh(ExplodeModifierData *emd, | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |                          ParticleSystemModifierData *psmd, | 
					
						
							|  |  |  |                          const ModifierEvalContext *ctx, | 
					
						
							|  |  |  |                          Scene *scene, | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |                          Mesh *to_explode) | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   Mesh *explode, *mesh = to_explode; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   MFace *mf = NULL, *mface; | 
					
						
							|  |  |  |   /* ParticleSettings *part=psmd->psys->part; */ /* UNUSED */ | 
					
						
							|  |  |  |   ParticleSimulationData sim = {NULL}; | 
					
						
							|  |  |  |   ParticleData *pa = NULL, *pars = psmd->psys->particles; | 
					
						
							|  |  |  |   ParticleKey state, birth; | 
					
						
							|  |  |  |   EdgeHash *vertpahash; | 
					
						
							|  |  |  |   EdgeHashIterator *ehi; | 
					
						
							|  |  |  |   float *vertco = NULL, imat[4][4]; | 
					
						
							|  |  |  |   float rot[4]; | 
					
						
							|  |  |  |   float cfra; | 
					
						
							|  |  |  |   /* float timestep; */ | 
					
						
							|  |  |  |   const int *facepa = emd->facepa; | 
					
						
							|  |  |  |   int totdup = 0, totvert = 0, totface = 0, totpart = 0, delface = 0; | 
					
						
							|  |  |  |   int i, v, u; | 
					
						
							| 
									
										
										
										
											2019-09-19 13:32:36 +10:00
										 |  |  |   uint ed_v1, ed_v2, mindex = 0; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   MTFace *mtface = NULL, *mtf; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   totface = mesh->totface; | 
					
						
							|  |  |  |   totvert = mesh->totvert; | 
					
						
							|  |  |  |   mface = mesh->mface; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   totpart = psmd->psys->totpart; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |   sim.depsgraph = ctx->depsgraph; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   sim.scene = scene; | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |   sim.ob = ctx->object; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   sim.psys = psmd->psys; | 
					
						
							|  |  |  |   sim.psmd = psmd; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* timestep = psys_get_timestep(&sim); */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   cfra = BKE_scene_frame_get(scene); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* hash table for vertice <-> particle relations */ | 
					
						
							|  |  |  |   vertpahash = BLI_edgehash_new(__func__); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (i = 0; i < totface; i++) { | 
					
						
							|  |  |  |     if (facepa[i] != totpart) { | 
					
						
							|  |  |  |       pa = pars + facepa[i]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       if ((pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) || | 
					
						
							|  |  |  |           (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) || | 
					
						
							|  |  |  |           (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0)) { | 
					
						
							|  |  |  |         delface++; | 
					
						
							|  |  |  |         continue; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-22 18:48:00 +02:00
										 |  |  |     else { | 
					
						
							|  |  |  |       pa = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     /* do mindex + totvert to ensure the vertex index to be the first
 | 
					
						
							|  |  |  |      * with BLI_edgehashIterator_getKey */ | 
					
						
							| 
									
										
										
										
											2019-09-22 18:48:00 +02:00
										 |  |  |     if (pa == NULL || cfra < pa->time) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       mindex = totvert + totpart; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       mindex = totvert + facepa[i]; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     mf = &mface[i]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     /* set face vertices to exist in particle group */ | 
					
						
							|  |  |  |     BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL); | 
					
						
							|  |  |  |     BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL); | 
					
						
							|  |  |  |     BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL); | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (mf->v4) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* make new vertice indexes & count total vertices after duplication */ | 
					
						
							|  |  |  |   ehi = BLI_edgehashIterator_new(vertpahash); | 
					
						
							|  |  |  |   for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | 
					
						
							| 
									
										
										
										
											2018-09-19 12:05:58 +10:00
										 |  |  |     BLI_edgehashIterator_setValue(ehi, POINTER_FROM_INT(totdup)); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     totdup++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   BLI_edgehashIterator_free(ehi); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* the final duplicated vertices */ | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* getting back to object space */ | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |   invert_m4_m4(imat, ctx->object->obmat); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /* duplicate & displace vertices */ | 
					
						
							|  |  |  |   ehi = BLI_edgehashIterator_new(vertpahash); | 
					
						
							|  |  |  |   for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { | 
					
						
							|  |  |  |     MVert source; | 
					
						
							|  |  |  |     MVert *dest; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     /* get particle + vertex from hash */ | 
					
						
							|  |  |  |     BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); | 
					
						
							|  |  |  |     ed_v2 -= totvert; | 
					
						
							| 
									
										
										
										
											2018-09-19 12:05:58 +10:00
										 |  |  |     v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     source = mesh->mvert[ed_v1]; | 
					
						
							|  |  |  |     dest = &explode->mvert[v]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     *dest = source; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (ed_v2 != totpart) { | 
					
						
							|  |  |  |       /* get particle */ | 
					
						
							|  |  |  |       pa = pars + ed_v2; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       psys_get_birth_coords(&sim, pa, &birth, 0, 0); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       state.time = cfra; | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |       psys_get_particle_state(&sim, ed_v2, &state, 1); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       vertco = explode->mvert[v].co; | 
					
						
							|  |  |  |       mul_m4_v3(ctx->object->obmat, vertco); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       sub_v3_v3(vertco, birth.co); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       /* apply rotation, size & location */ | 
					
						
							|  |  |  |       sub_qt_qtqt(rot, state.rot, birth.rot); | 
					
						
							|  |  |  |       mul_qt_v3(rot, vertco); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (emd->flag & eExplodeFlag_PaSize) { | 
					
						
							|  |  |  |         mul_v3_fl(vertco, pa->size); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       add_v3_v3(vertco, state.co); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       mul_m4_v3(imat, vertco); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-22 18:48:00 +02:00
										 |  |  |     else { | 
					
						
							|  |  |  |       pa = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   BLI_edgehashIterator_free(ehi); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   /*map new vertices to faces*/ | 
					
						
							|  |  |  |   for (i = 0, u = 0; i < totface; i++) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     MFace source; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     int orig_v4; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (facepa[i] != totpart) { | 
					
						
							|  |  |  |       pa = pars + facepa[i]; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |       if (pa->alive == PARS_UNBORN && (emd->flag & eExplodeFlag_Unborn) == 0) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (pa->alive == PARS_ALIVE && (emd->flag & eExplodeFlag_Alive) == 0) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (pa->alive == PARS_DEAD && (emd->flag & eExplodeFlag_Dead) == 0) { | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  |         continue; | 
					
						
							| 
									
										
										
										
											2019-04-22 09:15:10 +10:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-22 18:48:00 +02:00
										 |  |  |     else { | 
					
						
							|  |  |  |       pa = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     source = mesh->mface[i]; | 
					
						
							|  |  |  |     mf = &explode->mface[u]; | 
					
						
							| 
									
										
										
										
											2018-06-17 17:04:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     orig_v4 = source.v4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-22 18:51:45 +02:00
										 |  |  |     /* Same as above in the first loop over mesh's faces. */ | 
					
						
							|  |  |  |     if (pa == NULL || cfra < pa->time) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       mindex = totvert + totpart; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     else { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       mindex = totvert + facepa[i]; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     source.v1 = edgecut_get(vertpahash, source.v1, mindex); | 
					
						
							|  |  |  |     source.v2 = edgecut_get(vertpahash, source.v2, mindex); | 
					
						
							|  |  |  |     source.v3 = edgecut_get(vertpahash, source.v3, mindex); | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (source.v4) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       source.v4 = edgecut_get(vertpahash, source.v4, mindex); | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     CustomData_copy_data(&mesh->fdata, &explode->fdata, i, u, 1); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     *mf = source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* override uv channel for particle age */ | 
					
						
							|  |  |  |     if (mtface) { | 
					
						
							| 
									
										
										
										
											2019-09-22 18:48:00 +02:00
										 |  |  |       float age = (pa != NULL) ? (cfra - pa->time) / pa->lifetime : 0.0f; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       /* Clamp to this range to avoid flipping to the other side of the coordinates. */ | 
					
						
							|  |  |  |       CLAMP(age, 0.001f, 0.999f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       mtf = mtface + u; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = age; | 
					
						
							|  |  |  |       mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = 0.5f; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     test_index_face(mf, &explode->fdata, u, (orig_v4 ? 4 : 3)); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     u++; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* cleanup */ | 
					
						
							|  |  |  |   BLI_edgehash_free(vertpahash, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* finalization */ | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   BKE_mesh_calc_edges_tessface(explode); | 
					
						
							|  |  |  |   BKE_mesh_convert_mfaces_to_mpolys(explode); | 
					
						
							|  |  |  |   explode->runtime.cd_dirty_vert |= CD_MASK_NORMAL; | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (psmd->psys->lattice_deform_data) { | 
					
						
							| 
									
										
										
										
											2020-06-13 15:41:34 +10:00
										 |  |  |     BKE_lattice_deform_data_destroy(psmd->psys->lattice_deform_data); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     psmd->psys->lattice_deform_data = NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return explode; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, ModifierData *emd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   ModifierData *md; | 
					
						
							|  |  |  |   ParticleSystemModifierData *psmd = NULL; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   for (md = ob->modifiers.first; emd != md; md = md->next) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (md->type == eModifierType_ParticleSystem) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       psmd = (ParticleSystemModifierData *)md; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   return psmd; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-04-21 13:09:41 +02:00
										 |  |  | static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   ExplodeModifierData *emd = (ExplodeModifierData *)md; | 
					
						
							| 
									
										
										
										
											2018-05-01 17:33:04 +02:00
										 |  |  |   ParticleSystemModifierData *psmd = findPrecedingParticlesystem(ctx->object, md); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   if (psmd) { | 
					
						
							|  |  |  |     ParticleSystem *psys = psmd->psys; | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     if (psys == NULL || psys->totpart == 0) { | 
					
						
							|  |  |  |       return mesh; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (psys->part == NULL || psys->particles == NULL) { | 
					
						
							|  |  |  |       return mesh; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 11:49:43 +02:00
										 |  |  |     if (psmd->mesh_final == NULL) { | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |       return mesh; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |     BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     /* 1. find faces to be exploded if needed */ | 
					
						
							|  |  |  |     if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars || | 
					
						
							|  |  |  |         emd->flag & eExplodeFlag_CalcFaces || | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |         MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) { | 
					
						
							|  |  |  |       if (psmd->flag & eParticleSystemFlag_Pars) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         psmd->flag &= ~eParticleSystemFlag_Pars; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       if (emd->flag & eExplodeFlag_CalcFaces) { | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |         emd->flag &= ~eExplodeFlag_CalcFaces; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |       } | 
					
						
							|  |  |  |       createFacepa(emd, psmd, mesh); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     /* 2. create new mesh */ | 
					
						
							| 
									
										
										
										
											2018-06-22 15:03:42 +02:00
										 |  |  |     Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |     if (emd->flag & eExplodeFlag_EdgeCut) { | 
					
						
							|  |  |  |       int *facepa = emd->facepa; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |       Mesh *split_m = cutEdges(emd, mesh); | 
					
						
							|  |  |  |       Mesh *explode = explodeMesh(emd, psmd, ctx, scene, split_m); | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       MEM_freeN(emd->facepa); | 
					
						
							|  |  |  |       emd->facepa = facepa; | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |       BKE_id_free(NULL, split_m); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |       return explode; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-07 12:40:29 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return explodeMesh(emd, psmd, ctx, scene, mesh); | 
					
						
							| 
									
										
										
										
											2016-12-28 17:30:58 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-09-25 12:35:43 +02:00
										 |  |  |   return mesh; | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  | static void panel_draw(const bContext *UNUSED(C), Panel *panel) | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | { | 
					
						
							| 
									
										
											  
											
												UI: Small Tweaks to Modifier Layouts for Consistency
These changes are smaller, made based on feedback and a pass on all
the layouts for clarity and consistency. The Multires modifier UI will
be addressed in a separate patch. Here is an overview of the changes:
Renaming Options:
  - Build: "Start" -> "Start Frame"
  - Curve: "From Radius" -> "Size from Radius"
  - Screw: "Calc Order" -> "Calculate Order"
  - Displace, Warp, Wave: "Texture Coordinates Object" -> "Object"
Move Mode Toggle to Top & Expand:
  - Bevel, Boolean, Normal Edit, Subdivision
Use Columns for Tighter Spacing:
  - Displace, Explode, Ocean, Particle Instance, Remesh, Shrinkwrap,
    Solidify, Warp, Weighted Normal, Wave
Misc:
  - Bevel: Set inactive properties for vertex bevel
  - Mesh Sequence Cache: Remove box for cache file
  - Skin: Don't align "Mark Loose" and "Clear Loose"
  - Array: Expand relative offset subpanel by default
  - Array: Move start cap, end cap to a new subpanel
  - Bevel: Move width type above width
Differential Revision: https://developer.blender.org/D8115
											
										 
											2020-07-02 10:47:02 -04:00
										 |  |  |   uiLayout *row, *col; | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  |   uiLayout *layout = panel->layout; | 
					
						
							|  |  |  |   int toggles_flag = UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   PointerRNA ob_ptr; | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   PointerRNA *ptr = modifier_panel_get_property_pointers(panel, &ob_ptr); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PointerRNA obj_data_ptr = RNA_pointer_get(&ob_ptr, "data"); | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   bool has_vertex_group = RNA_string_length(ptr, "vertex_group") != 0; | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   uiLayoutSetPropSep(layout, true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   uiItemPointerR(layout, ptr, "particle_uv", &obj_data_ptr, "uv_layers", NULL, ICON_NONE); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   row = uiLayoutRowWithHeading(layout, true, IFACE_("Show")); | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   uiItemR(row, ptr, "show_alive", toggles_flag, NULL, ICON_NONE); | 
					
						
							|  |  |  |   uiItemR(row, ptr, "show_dead", toggles_flag, NULL, ICON_NONE); | 
					
						
							|  |  |  |   uiItemR(row, ptr, "show_unborn", toggles_flag, NULL, ICON_NONE); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   uiLayoutSetPropSep(layout, true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												UI: Small Tweaks to Modifier Layouts for Consistency
These changes are smaller, made based on feedback and a pass on all
the layouts for clarity and consistency. The Multires modifier UI will
be addressed in a separate patch. Here is an overview of the changes:
Renaming Options:
  - Build: "Start" -> "Start Frame"
  - Curve: "From Radius" -> "Size from Radius"
  - Screw: "Calc Order" -> "Calculate Order"
  - Displace, Warp, Wave: "Texture Coordinates Object" -> "Object"
Move Mode Toggle to Top & Expand:
  - Bevel, Boolean, Normal Edit, Subdivision
Use Columns for Tighter Spacing:
  - Displace, Explode, Ocean, Particle Instance, Remesh, Shrinkwrap,
    Solidify, Warp, Weighted Normal, Wave
Misc:
  - Bevel: Set inactive properties for vertex bevel
  - Mesh Sequence Cache: Remove box for cache file
  - Skin: Don't align "Mark Loose" and "Clear Loose"
  - Array: Expand relative offset subpanel by default
  - Array: Move start cap, end cap to a new subpanel
  - Bevel: Move width type above width
Differential Revision: https://developer.blender.org/D8115
											
										 
											2020-07-02 10:47:02 -04:00
										 |  |  |   col = uiLayoutColumn(layout, false); | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   uiItemR(col, ptr, "use_edge_cut", 0, NULL, ICON_NONE); | 
					
						
							|  |  |  |   uiItemR(col, ptr, "use_size", 0, NULL, ICON_NONE); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   row = uiLayoutRow(layout, false); | 
					
						
							|  |  |  |   uiLayoutSetActive(row, has_vertex_group); | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   uiItemR(row, ptr, "protect", 0, NULL, ICON_NONE); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |   uiItemO(layout, IFACE_("Refresh"), ICON_NONE, "OBJECT_OT_explode_refresh"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 14:13:26 -05:00
										 |  |  |   modifier_panel_end(layout, ptr); | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void panelRegister(ARegionType *region_type) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   modifier_panel_register(region_type, eModifierType_Explode, panel_draw); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-23 17:25:44 +02:00
										 |  |  | static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   ExplodeModifierData *psmd = (ExplodeModifierData *)md; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   psmd->facepa = NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | ModifierTypeInfo modifierType_Explode = { | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  |     /* name */ "Explode", | 
					
						
							|  |  |  |     /* structName */ "ExplodeModifierData", | 
					
						
							|  |  |  |     /* structSize */ sizeof(ExplodeModifierData), | 
					
						
							| 
									
										
										
										
											2020-09-25 12:49:18 +02:00
										 |  |  |     /* srna */ &RNA_ExplodeModifier, | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  |     /* type */ eModifierTypeType_Constructive, | 
					
						
							|  |  |  |     /* flags */ eModifierTypeFlag_AcceptsMesh, | 
					
						
							| 
									
										
										
										
											2020-09-25 12:45:30 +02:00
										 |  |  |     /* icon */ ICON_MOD_EXPLODE, | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  |     /* copyData */ copyData, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  |     /* deformVerts */ NULL, | 
					
						
							|  |  |  |     /* deformMatrices */ NULL, | 
					
						
							|  |  |  |     /* deformVertsEM */ NULL, | 
					
						
							|  |  |  |     /* deformMatricesEM */ NULL, | 
					
						
							| 
									
										
										
										
											2020-04-21 13:09:41 +02:00
										 |  |  |     /* modifyMesh */ modifyMesh, | 
					
						
							|  |  |  |     /* modifyHair */ NULL, | 
					
						
							| 
									
										
										
										
											2020-12-10 14:35:02 +01:00
										 |  |  |     /* modifyGeometrySet */ NULL, | 
					
						
							| 
									
										
										
										
											2020-04-21 13:09:41 +02:00
										 |  |  |     /* modifyVolume */ NULL, | 
					
						
							| 
									
										
										
										
											2019-04-17 06:17:24 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  |     /* initData */ initData, | 
					
						
							|  |  |  |     /* requiredDataMask */ requiredDataMask, | 
					
						
							|  |  |  |     /* freeData */ freeData, | 
					
						
							|  |  |  |     /* 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, | 
					
						
							| 
									
										
										
										
											2012-10-24 05:45:54 +00:00
										 |  |  |     /* dependsOnTime */ dependsOnTime, | 
					
						
							|  |  |  |     /* dependsOnNormals */ NULL, | 
					
						
							|  |  |  |     /* foreachIDLink */ NULL, | 
					
						
							|  |  |  |     /* foreachTexLink */ NULL, | 
					
						
							| 
									
										
										
										
											2019-03-18 15:56:16 +01:00
										 |  |  |     /* freeRuntimeData */ NULL, | 
					
						
							| 
									
										
										
										
											2020-06-05 10:41:03 -04:00
										 |  |  |     /* panelRegister */ panelRegister, | 
					
						
							| 
									
										
										
										
											2020-06-15 17:37:07 +02:00
										 |  |  |     /* blendWrite */ NULL, | 
					
						
							| 
									
										
										
										
											2020-06-23 17:25:44 +02:00
										 |  |  |     /* blendRead */ blendRead, | 
					
						
							| 
									
										
										
										
											2010-04-11 22:12:30 +00:00
										 |  |  | }; |