Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / physics / particle_object.c
index 8a36327..48a80cb 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_scene_types.h"
 #include "BLI_string.h"
 
 #include "BKE_context.h"
-#include "BKE_depsgraph.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_cdderivedmesh.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
+#include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 #include "BKE_report.h"
 
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
 #include "RNA_access.h"
 #include "RNA_define.h"
 
@@ -110,6 +114,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *ob = ED_object_context(C);
        Scene *scene = CTX_data_scene(C);
+       ViewLayer *view_layer = CTX_data_view_layer(C);
        int mode_orig;
 
        if (!scene || !ob)
@@ -123,7 +128,7 @@ static int particle_system_remove_exec(bContext *C, wmOperator *UNUSED(op))
         */
        if (mode_orig & OB_MODE_PARTICLE_EDIT) {
                if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0) {
-                       if (scene->basact && scene->basact->object == ob) {
+                       if (view_layer->basact && view_layer->basact->object == ob) {
                                WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, NULL);
                        }
                }
@@ -185,8 +190,8 @@ static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
 
        psys_check_boid_data(psys);
 
-       DAG_relations_tag_update(bmain);
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_relations_tag_update(bmain);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
 
@@ -233,8 +238,8 @@ static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
 
        BLI_addtail(&psys->targets, pt);
 
-       DAG_relations_tag_update(bmain);
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_relations_tag_update(bmain);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
 
@@ -281,8 +286,8 @@ static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
        if (pt)
                pt->flag |= PTARGET_CURRENT;
 
-       DAG_relations_tag_update(bmain);
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_relations_tag_update(bmain);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
 
@@ -321,7 +326,7 @@ static int target_move_up_exec(bContext *C, wmOperator *UNUSED(op))
                        BLI_remlink(&psys->targets, pt);
                        BLI_insertlinkbefore(&psys->targets, pt->prev, pt);
 
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
                        break;
                }
@@ -359,7 +364,7 @@ static int target_move_down_exec(bContext *C, wmOperator *UNUSED(op))
                        BLI_remlink(&psys->targets, pt);
                        BLI_insertlinkafter(&psys->targets, pt->next, pt);
 
-                       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+                       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
                        break;
                }
@@ -542,7 +547,9 @@ void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
 
 /************************ connect/disconnect hair operators *********************/
 
-static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static void disconnect_hair(
+        Depsgraph *depsgraph, Scene *scene,
+        Object *ob, ParticleSystem *psys)
 {
        ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
        ParticleEditSettings *pset= PE_settings(scene);
@@ -569,7 +576,7 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
                        point++;
                }
 
-               psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, pa, hairmat);
+               psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat);
 
                for (k=0, key=pa->hair; k<pa->totkey; k++, key++) {
                        mul_m4_v3(hairmat, key->co);
@@ -588,11 +595,12 @@ static void disconnect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
        if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF))
                pset->brushtype = PE_BRUSH_NONE;
 
-       PE_update_object(scene, ob, 0);
+       PE_update_object(depsgraph, scene, ob, 0);
 }
 
 static int disconnect_hair_exec(bContext *C, wmOperator *op)
 {
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= ED_object_context(C);
        ParticleSystem *psys= NULL;
@@ -603,15 +611,15 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op)
 
        if (all) {
                for (psys=ob->particlesystem.first; psys; psys=psys->next) {
-                       disconnect_hair(scene, ob, psys);
+                       disconnect_hair(depsgraph, scene, ob, psys);
                }
        }
        else {
                psys = psys_get_current(ob);
-               disconnect_hair(scene, ob, psys);
+               disconnect_hair(depsgraph, scene, ob, psys);
        }
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
 
        return OPERATOR_FINISHED;
@@ -634,9 +642,10 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
 /* from/to_world_space : whether from/to particles are in world or hair space
  * from/to_mat : additional transform for from/to particles (e.g. for using object space copying)
  */
-static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
-                               Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
-                               float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
+static bool remap_hair_emitter(
+        Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys,
+        Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
+        float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
 {
        ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys);
        ParticleData *pa, *tpa;
@@ -646,13 +655,13 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
        MFace *mface = NULL, *mf;
        MEdge *medge = NULL, *me;
        MVert *mvert;
-       DerivedMesh *dm, *target_dm;
+       Mesh *mesh, *target_mesh;
        int numverts;
        int i, k;
        float from_ob_imat[4][4], to_ob_imat[4][4];
        float from_imat[4][4], to_imat[4][4];
 
-       if (!target_psmd->dm_final)
+       if (!target_psmd->mesh_final)
                return false;
        if (!psys->part || psys->part->type != PART_HAIR)
                return false;
@@ -666,40 +675,46 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
        invert_m4_m4(from_imat, from_mat);
        invert_m4_m4(to_imat, to_mat);
 
-       if (target_psmd->dm_final->deformedOnly) {
+       if (target_psmd->mesh_final->runtime.deformed_only) {
                /* we don't want to mess up target_psmd->dm when converting to global coordinates below */
-               dm = target_psmd->dm_final;
+               mesh = target_psmd->mesh_final;
        }
        else {
-               dm = target_psmd->dm_deformed;
+               mesh = target_psmd->mesh_original;
        }
-       target_dm = target_psmd->dm_final;
-       if (dm == NULL) {
+       target_mesh = target_psmd->mesh_final;
+       if (mesh == NULL) {
                return false;
        }
        /* don't modify the original vertices */
-       dm = CDDM_copy(dm);
+       BKE_id_copy_ex(
+                   NULL, &mesh->id, (ID **)&mesh,
+                   LIB_ID_CREATE_NO_MAIN |
+                   LIB_ID_CREATE_NO_USER_REFCOUNT |
+                   LIB_ID_CREATE_NO_DEG_TAG |
+                   LIB_ID_COPY_NO_PREVIEW,
+                   false);
 
        /* BMESH_ONLY, deform dm may not have tessface */
-       DM_ensure_tessface(dm);
+       BKE_mesh_tessface_ensure(mesh);
 
-       numverts = dm->getNumVerts(dm);
-       mvert = dm->getVertArray(dm);
+       numverts = mesh->totvert;
+       mvert = mesh->mvert;
 
        /* convert to global coordinates */
        for (i=0; i<numverts; i++)
                mul_m4_v3(to_mat, mvert[i].co);
 
-       if (dm->getNumTessFaces(dm) != 0) {
-               mface = dm->getTessFaceArray(dm);
-               bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_FACES, 2);
+       if (mesh->totface != 0) {
+               mface = mesh->mface;
+               BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_FACES, 2);
        }
-       else if (dm->getNumEdges(dm) != 0) {
-               medge = dm->getEdgeArray(dm);
-               bvhtree_from_mesh_get(&bvhtree, dm, BVHTREE_FROM_EDGES, 2);
+       else if (mesh->totedge != 0) {
+               medge = mesh->medge;
+               BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_EDGES, 2);
        }
        else {
-               dm->release(dm);
+               BKE_id_free(NULL, mesh);
                return false;
        }
 
@@ -744,7 +759,7 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
                        tpa->foffset = 0.0f;
 
                        tpa->num = nearest.index;
-                       tpa->num_dmcache = psys_particle_dm_face_lookup(target_dm, dm, tpa->num, tpa->fuv, NULL);
+                       tpa->num_dmcache = psys_particle_dm_face_lookup(target_mesh, mesh, tpa->num, tpa->fuv, NULL);
                }
                else {
                        me = &medge[nearest.index];
@@ -770,7 +785,7 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
                                copy_m4_m4(imat, target_ob->obmat);
                        else {
                                /* note: using target_dm here, which is in target_ob object space and has full modifiers */
-                               psys_mat_hair_to_object(target_ob, target_dm, target_psys->part->from, tpa, hairmat);
+                               psys_mat_hair_to_object(target_ob, target_mesh, target_psys->part->from, tpa, hairmat);
                                invert_m4_m4(imat, hairmat);
                        }
                        mul_m4_m4m4(imat, imat, to_imat);
@@ -816,23 +831,27 @@ static bool remap_hair_emitter(Scene *scene, Object *ob, ParticleSystem *psys,
        }
 
        free_bvhtree_from_mesh(&bvhtree);
-       dm->release(dm);
+       BKE_id_free(NULL, mesh);
 
        psys_free_path_cache(target_psys, target_edit);
 
-       PE_update_object(scene, target_ob, 0);
+       PE_update_object(depsgraph, scene, target_ob, 0);
 
        return true;
 }
 
-static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
+static bool connect_hair(
+        Depsgraph *depsgraph, Scene *scene,
+        Object *ob, ParticleSystem *psys)
 {
        bool ok;
 
        if (!psys)
                return false;
 
-       ok = remap_hair_emitter(scene, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
+       ok = remap_hair_emitter(
+                depsgraph, scene, ob, psys, ob, psys, psys->edit,
+                ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
        psys->flag &= ~PSYS_GLOBAL_HAIR;
 
        return ok;
@@ -840,6 +859,7 @@ static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
 
 static int connect_hair_exec(bContext *C, wmOperator *op)
 {
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Scene *scene= CTX_data_scene(C);
        Object *ob= ED_object_context(C);
        ParticleSystem *psys= NULL;
@@ -851,12 +871,12 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
 
        if (all) {
                for (psys=ob->particlesystem.first; psys; psys=psys->next) {
-                       any_connected |= connect_hair(scene, ob, psys);
+                       any_connected |= connect_hair(depsgraph, scene, ob, psys);
                }
        }
        else {
                psys = psys_get_current(ob);
-               any_connected |= connect_hair(scene, ob, psys);
+               any_connected |= connect_hair(depsgraph, scene, ob, psys);
        }
 
        if (!any_connected) {
@@ -865,7 +885,7 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
-       DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
 
        return OPERATOR_FINISHED;
@@ -892,7 +912,9 @@ typedef enum eCopyParticlesSpace {
        PAR_COPY_SPACE_WORLD    = 1,
 } eCopyParticlesSpace;
 
-static void copy_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
+static void copy_particle_edit(
+        Depsgraph *depsgraph, Scene *scene,
+        Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
 {
        PTCacheEdit *edit_from = psys_from->edit, *edit;
        ParticleData *pa;
@@ -932,14 +954,14 @@ static void copy_particle_edit(Scene *scene, Object *ob, ParticleSystem *psys, P
 
                pa++;
        }
-       update_world_cos(ob, edit);
+       update_world_cos(depsgraph, ob, edit);
 
        UI_GetThemeColor3ubv(TH_EDGE_SELECT, edit->sel_col);
        UI_GetThemeColor3ubv(TH_WIRE, edit->nosel_col);
 
        recalc_lengths(edit);
-       recalc_emitter_field(ob, psys);
-       PE_update_object(scene, ob, true);
+       recalc_emitter_field(depsgraph, ob, psys);
+       PE_update_object(depsgraph, scene, ob, true);
 }
 
 static void remove_particle_systems_from_object(Object *ob_to)
@@ -967,7 +989,7 @@ static void remove_particle_systems_from_object(Object *ob_to)
 }
 
 /* single_psys_from is optional, if NULL all psys of ob_from are copied */
-static bool copy_particle_systems_to_object(Main *bmain,
+static bool copy_particle_systems_to_object(const bContext *C,
                                             Scene *scene,
                                             Object *ob_from,
                                             ParticleSystem *single_psys_from,
@@ -975,10 +997,12 @@ static bool copy_particle_systems_to_object(Main *bmain,
                                             int space,
                                             bool duplicate_settings)
 {
+       Main *bmain = CTX_data_main(C);
+       Depsgraph *depsgraph = CTX_data_depsgraph(C);
        ModifierData *md;
        ParticleSystem *psys_start = NULL, *psys, *psys_from;
        ParticleSystem **tmp_psys;
-       DerivedMesh *final_dm;
+       Mesh *final_mesh;
        CustomDataMask cdmask;
        int i, totpsys;
 
@@ -1020,7 +1044,10 @@ static bool copy_particle_systems_to_object(Main *bmain,
        psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
 
        /* get the DM (psys and their modifiers have not been appended yet) */
-       final_dm = mesh_get_derived_final(scene, ob_to, cdmask);
+       /* TODO(Sybren): use mesh_eval instead */
+       DerivedMesh *final_dm = mesh_get_derived_final(depsgraph, scene, ob_to, cdmask);
+       final_mesh = BKE_id_new_nomain(ID_ME, NULL);
+       DM_to_mesh(final_dm, final_mesh, ob_to, CD_MASK_EVERYTHING, false);
 
        /* now append psys to the object and make modifiers */
        for (i = 0, psys_from = PSYS_FROM_FIRST;
@@ -1044,12 +1071,20 @@ static bool copy_particle_systems_to_object(Main *bmain,
                modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
 
                psmd->psys = psys;
-               psmd->dm_final = CDDM_copy(final_dm);
-               CDDM_calc_normals(psmd->dm_final);
-               DM_ensure_tessface(psmd->dm_final);
-
-               if (psys_from->edit)
-                       copy_particle_edit(scene, ob_to, psys, psys_from);
+               BKE_id_copy_ex(
+                           NULL, &final_mesh->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_calc_normals(psmd->mesh_final);
+               BKE_mesh_tessface_ensure(psmd->mesh_final);
+
+               if (psys_from->edit) {
+                       copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from);
+               }
 
                if (duplicate_settings) {
                        id_us_min(&psys->part->id);
@@ -1083,7 +1118,9 @@ static bool copy_particle_systems_to_object(Main *bmain,
                                break;
                }
                if (ob_from != ob_to) {
-                       remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
+                       remap_hair_emitter(
+                               depsgraph, scene, ob_from, psys_from, ob_to, psys, psys->edit,
+                               from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
                }
 
                /* tag for recalc */
@@ -1093,7 +1130,7 @@ static bool copy_particle_systems_to_object(Main *bmain,
        #undef PSYS_FROM_FIRST
        #undef PSYS_FROM_NEXT
 
-       DAG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
+       DEG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
        WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
        return true;
 }
@@ -1116,7 +1153,6 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
        const int space = RNA_enum_get(op->ptr, "space");
        const bool remove_target_particles = RNA_boolean_get(op->ptr, "remove_target_particles");
        const bool use_active = RNA_boolean_get(op->ptr, "use_active");
-       Main *bmain = CTX_data_main(C);
        Scene *scene = CTX_data_scene(C);
        Object *ob_from = ED_object_active_context(C);
        ParticleSystem *psys_from = use_active ? CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data : NULL;
@@ -1132,7 +1168,7 @@ static int copy_particle_systems_exec(bContext *C, wmOperator *op)
                                remove_particle_systems_from_object(ob_to);
                                changed = true;
                        }
-                       if (copy_particle_systems_to_object(bmain, scene, ob_from, psys_from, ob_to, space, false))
+                       if (copy_particle_systems_to_object(C, scene, ob_from, psys_from, ob_to, space, false))
                                changed = true;
                        else
                                fail++;
@@ -1193,7 +1229,7 @@ static int duplicate_particle_systems_exec(bContext *C, wmOperator *op)
        Scene *scene = CTX_data_scene(C);
        Object *ob = ED_object_active_context(C);
        ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
-       copy_particle_systems_to_object(CTX_data_main(C), scene, ob, psys, ob,
+       copy_particle_systems_to_object(C, scene, ob, psys, ob,
                                        PAR_COPY_SPACE_OBJECT, duplicate_settings);
        return OPERATOR_FINISHED;
 }