Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/modifiers/intern/MOD_particlesystem.c')
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c167
1 files changed, 99 insertions, 68 deletions
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index 80b6c16b382..784e44f5758 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -42,33 +42,34 @@
#include "BKE_cdderivedmesh.h"
-#include "BKE_global.h"
+#include "BKE_editmesh.h"
+#include "BKE_mesh.h"
+#include "BKE_library.h"
#include "BKE_modifier.h"
#include "BKE_particle.h"
-#include "MOD_util.h"
+#include "DEG_depsgraph_query.h"
+#include "MOD_util.h"
static void initData(ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
psmd->psys = NULL;
- psmd->dm_final = NULL;
- psmd->dm_deformed = NULL;
+ psmd->mesh_final = NULL;
+ psmd->mesh_original = NULL;
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
}
static void freeData(ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- if (psmd->dm_final) {
- psmd->dm_final->needsFree = true;
- psmd->dm_final->release(psmd->dm_final);
- psmd->dm_final = NULL;
- if (psmd->dm_deformed) {
- psmd->dm_deformed->needsFree = true;
- psmd->dm_deformed->release(psmd->dm_deformed);
- psmd->dm_deformed = NULL;
+ if (psmd->mesh_final) {
+ BKE_id_free(NULL, psmd->mesh_final);
+ psmd->mesh_final = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
}
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
@@ -88,8 +89,8 @@ static void copyData(const ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
- tpsmd->dm_final = NULL;
- tpsmd->dm_deformed = NULL;
+ tpsmd->mesh_final = NULL;
+ tpsmd->mesh_original = NULL;
tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
}
@@ -101,47 +102,42 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
/* saves the current emitter state for a particle system and calculates particles */
static void deformVerts(
- ModifierData *md, Object *ob,
- DerivedMesh *derivedData,
+ ModifierData *md, const ModifierEvalContext *ctx,
+ Mesh *mesh,
float (*vertexCos)[3],
- int UNUSED(numVerts),
- ModifierApplyFlag flag)
+ int UNUSED(numVerts))
{
- DerivedMesh *dm = derivedData;
+ Mesh *mesh_src = mesh;
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
ParticleSystem *psys = NULL;
- bool needsFree = false;
/* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */
- if (ob->particlesystem.first)
+ if (ctx->object->particlesystem.first)
psys = psmd->psys;
else
return;
- if (!psys_check_enabled(ob, psys, (flag & MOD_APPLY_RENDER) != 0))
+ if (!psys_check_enabled(ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0))
return;
- if (dm == NULL) {
- dm = get_dm(ob, NULL, NULL, vertexCos, false, true);
-
- if (!dm)
+ if (mesh_src == NULL) {
+ mesh_src = get_mesh(ctx->object, NULL, NULL, vertexCos, false, true);
+ if (mesh_src == NULL) {
return;
-
- needsFree = true;
+ }
}
/* clear old dm */
- if (psmd->dm_final) {
- psmd->dm_final->needsFree = true;
- psmd->dm_final->release(psmd->dm_final);
- if (psmd->dm_deformed) {
- psmd->dm_deformed->needsFree = 1;
- psmd->dm_deformed->release(psmd->dm_deformed);
- psmd->dm_deformed = NULL;
+ if (psmd->mesh_final) {
+ BKE_id_free(NULL, psmd->mesh_final);
+ psmd->mesh_final = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
}
else if (psmd->flag & eParticleSystemFlag_file_loaded) {
- /* in file read dm just wasn't saved in file so no need to reset everything */
+ /* in file read mesh just wasn't saved in file so no need to reset everything */
psmd->flag &= ~eParticleSystemFlag_file_loaded;
}
else {
@@ -149,48 +145,75 @@ static void deformVerts(
psys->recalc |= PSYS_RECALC_RESET;
}
- /* make new dm */
- psmd->dm_final = CDDM_copy(dm);
- CDDM_apply_vert_coords(psmd->dm_final, vertexCos);
- CDDM_calc_normals(psmd->dm_final);
-
- if (needsFree) {
- dm->needsFree = true;
- dm->release(dm);
- }
+ /* make new mesh */
+ BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_final,
+ LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_NO_PREVIEW,
+ false);
+ BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos);
+ BKE_mesh_calc_normals(psmd->mesh_final);
+
+ BKE_mesh_tessface_ensure(psmd->mesh_final);
+
+ if (!psmd->mesh_final->runtime.deformed_only) {
+ /* Get the original mesh from the object, this is what the particles
+ * are attached to so in case of non-deform modifiers we need to remap
+ * them to the final mesh (typically subdivision surfaces). */
+ Mesh *mesh_original = NULL;
+
+ if (ctx->object->type == OB_MESH) {
+ BMEditMesh *edit_btmesh = BKE_editmesh_from_object(ctx->object);
+
+ if (edit_btmesh) {
+ /* In edit mode get directly from the edit mesh. */
+ psmd->mesh_original = BKE_bmesh_to_mesh_nomain(edit_btmesh->bm, &(struct BMeshToMeshParams){0});
+ }
+ else {
+ /* Otherwise get regular mesh. */
+ mesh_original = ctx->object->data;
+ }
+ }
+ else {
+ mesh_original = mesh_src;
+ }
- /* protect dm */
- psmd->dm_final->needsFree = false;
+ if (mesh_original) {
+ /* Make a persistent copy of the mesh. We don't actually need
+ * all this data, just some topology for remapping. Could be
+ * optimized once. */
+ BKE_id_copy_ex(NULL, &mesh_original->id, (ID **)&psmd->mesh_original,
+ LIB_ID_CREATE_NO_MAIN |
+ LIB_ID_CREATE_NO_USER_REFCOUNT |
+ LIB_ID_CREATE_NO_DEG_TAG |
+ LIB_ID_COPY_NO_PREVIEW,
+ false);
+ }
- DM_ensure_tessface(psmd->dm_final);
+ BKE_mesh_tessface_ensure(psmd->mesh_original);
+ }
- if (!psmd->dm_final->deformedOnly) {
- /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set.
- * This is awfully weak though. :| */
- if (ob->derivedDeform) {
- psmd->dm_deformed = CDDM_copy(ob->derivedDeform);
- }
- else { /* Can happen in some cases, e.g. when rendering from Edit mode... */
- psmd->dm_deformed = CDDM_from_mesh((Mesh *)ob->data);
- }
- DM_ensure_tessface(psmd->dm_deformed);
+ if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
+ BKE_id_free(NULL, mesh_src);
}
/* report change in mesh structure */
- if (psmd->dm_final->getNumVerts(psmd->dm_final) != psmd->totdmvert ||
- psmd->dm_final->getNumEdges(psmd->dm_final) != psmd->totdmedge ||
- psmd->dm_final->getNumTessFaces(psmd->dm_final) != psmd->totdmface)
+ if (psmd->mesh_final->totvert != psmd->totdmvert ||
+ psmd->mesh_final->totedge != psmd->totdmedge ||
+ psmd->mesh_final->totface != psmd->totdmface)
{
psys->recalc |= PSYS_RECALC_RESET;
- psmd->totdmvert = psmd->dm_final->getNumVerts(psmd->dm_final);
- psmd->totdmedge = psmd->dm_final->getNumEdges(psmd->dm_final);
- psmd->totdmface = psmd->dm_final->getNumTessFaces(psmd->dm_final);
+ psmd->totdmvert = psmd->mesh_final->totvert;
+ psmd->totdmedge = psmd->mesh_final->totedge;
+ psmd->totdmface = psmd->mesh_final->totface;
}
- if (!(ob->transflag & OB_NO_PSYS_UPDATE)) {
+ if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
+ struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
psmd->flag &= ~eParticleSystemFlag_psys_updated;
- particle_system_update(G.main, md->scene, ob, psys, (flag & MOD_APPLY_RENDER) != 0);
+ particle_system_update(ctx->depsgraph, scene, ctx->object, psys, (ctx->flag & MOD_APPLY_RENDER) != 0);
psmd->flag |= eParticleSystemFlag_psys_updated;
}
}
@@ -225,17 +248,25 @@ ModifierTypeInfo modifierType_ParticleSystem = {
eModifierTypeFlag_EnableInEditmode */,
/* copyData */ copyData,
+
+ /* deformVerts_DM */ NULL,
+ /* deformVertsEM_DM */ NULL,
+ /* deformMatrices_DM */ NULL,
+ /* deformMatricesEM_DM*/NULL,
+ /* applyModifier_DM */ NULL,
+ /* applyModifierEM_DM */NULL,
+
/* deformVerts */ deformVerts,
- /* deformVertsEM */ NULL,
/* deformMatrices */ NULL,
+ /* deformVertsEM */ NULL,
/* deformMatricesEM */ NULL,
/* applyModifier */ NULL,
/* applyModifierEM */ NULL,
+
/* initData */ initData,
/* requiredDataMask */ requiredDataMask,
/* freeData */ freeData,
/* isDisabled */ NULL,
- /* updateDepgraph */ NULL,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,