Hair editing: Use original object's particles for drawing
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 15 Jun 2018 15:22:31 +0000 (17:22 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 15 Jun 2018 15:23:49 +0000 (17:23 +0200)
This allows to rely on brush to update children positions,
and avoid tag of object. Makes it way faster to comb with
children enabled.

source/blender/draw/intern/draw_cache_impl_particles.c
source/blender/editors/physics/particle_edit.c

index 380cb08962875c2843535aabe8e5f5e00adb2591..7024380d9bc5151b733e53ffb82acc328e8a4e17 100644 (file)
@@ -45,6 +45,7 @@
 #include "DNA_customdata_types.h"
 
 #include "BKE_mesh.h"
+#include "BKE_modifier.h"
 #include "BKE_particle.h"
 #include "BKE_pointcache.h"
 
@@ -1309,17 +1310,45 @@ static void drw_particle_update_ptcache(
        }
 }
 
+typedef struct ParticleDrawSource {
+       Object *object;
+       ParticleSystem *psys;
+       ModifierData *md;
+       PTCacheEdit *edit;
+} ParticleDrawSource;
+
+static void drw_particle_get_hair_source(
+    Object *object,
+    ParticleSystem *psys,
+       ModifierData *md,
+       PTCacheEdit *edit,
+       ParticleDrawSource *r_draw_source)
+{
+       r_draw_source->object = object;
+       r_draw_source->psys = psys;
+       r_draw_source->md = md;
+       r_draw_source->edit = edit;
+       if ((object->mode & OB_MODE_PARTICLE_EDIT) != 0) {
+               r_draw_source->object = DEG_get_original_object(object);
+               r_draw_source->psys = psys_orig_get(psys);
+               if (md != NULL) {
+                       r_draw_source->md = modifiers_findByName(r_draw_source->object, md->name);
+               }
+       }
+}
+
 Gwn_Batch *DRW_particles_batch_cache_get_hair(
         Object *object,
         ParticleSystem *psys,
         ModifierData *md)
 {
        ParticleBatchCache *cache = particle_batch_cache_get(psys);
-
        if (cache->hair.hairs == NULL) {
                drw_particle_update_ptcache(object, psys);
-               ensure_seg_pt_count(NULL, psys, &cache->hair);
-               particle_batch_cache_ensure_pos_and_seg(NULL, psys, md, &cache->hair);
+               ParticleDrawSource source;
+               drw_particle_get_hair_source(object, psys, md, NULL, &source);
+               ensure_seg_pt_count(source.edit, source.psys, &cache->hair);
+               particle_batch_cache_ensure_pos_and_seg(source.edit, source.psys, source.md, &cache->hair);
                cache->hair.hairs = GWN_batch_create(
                        GWN_PRIM_LINE_STRIP,
                        cache->hair.pos,
@@ -1515,7 +1544,7 @@ Gwn_Batch *DRW_particles_batch_cache_get_edit_tip_points(
 
 /* Ensure all textures and buffers needed for GPU accelerated drawing. */
 bool particles_ensure_procedural_data(
-        Object *UNUSED(object),
+        Object *object,
         ParticleSystem *psys,
         ModifierData *md,
         ParticleHairCache **r_hair_cache,
@@ -1524,22 +1553,27 @@ bool particles_ensure_procedural_data(
 {
        bool need_ft_update = false;
 
-       ParticleSettings *part = psys->part;
-       ParticleBatchCache *cache = particle_batch_cache_get(psys);
+       drw_particle_update_ptcache(object, psys);
+
+       ParticleDrawSource source;
+       drw_particle_get_hair_source(object, psys, md, NULL, &source);
+
+       ParticleSettings *part = source.psys->part;
+       ParticleBatchCache *cache = particle_batch_cache_get(source.psys);
        *r_hair_cache = &cache->hair;
 
        (*r_hair_cache)->final[subdiv].strands_res = 1 << (part->draw_step + subdiv);
 
        /* Refreshed on combing and simulation. */
        if ((*r_hair_cache)->proc_point_buf == NULL) {
-               ensure_seg_pt_count(NULL, psys, &cache->hair);
-               particle_batch_cache_ensure_procedural_pos(NULL, psys, &cache->hair);
+               ensure_seg_pt_count(source.edit, source.psys, &cache->hair);
+               particle_batch_cache_ensure_procedural_pos(source.edit, source.psys, &cache->hair);
                need_ft_update = true;
        }
 
        /* Refreshed if active layer or custom data changes. */
        if ((*r_hair_cache)->strand_tex == NULL) {
-               particle_batch_cache_ensure_procedural_strand_data(NULL, psys, md, &cache->hair);
+               particle_batch_cache_ensure_procedural_strand_data(source.edit, source.psys, source.md, &cache->hair);
        }
 
        /* Refreshed only on subdiv count change. */
@@ -1548,7 +1582,7 @@ bool particles_ensure_procedural_data(
                need_ft_update = true;
        }
        if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == NULL) {
-               particle_batch_cache_ensure_procedural_indices(NULL, psys, &cache->hair, thickness_res, subdiv);
+               particle_batch_cache_ensure_procedural_indices(source.edit, source.psys, &cache->hair, thickness_res, subdiv);
        }
 
 
index 0ba98d758c757edb52dfe505fb9a6a9131366ac0..1068eec58433aeecac550e0dc3919d8b495f798f 100644 (file)
@@ -4232,12 +4232,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
                if (edit->psys) {
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
                        BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
-                       if (pset->flag & PE_DRAW_PART) {
-                               DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
-                       }
-                       else {
-                               DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
-                       }
+                       DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
                }
                else {
                        DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -4505,12 +4500,7 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
                if (edit->psys) {
                        WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
                        BKE_particle_batch_cache_dirty(edit->psys, BKE_PARTICLE_BATCH_DIRTY_ALL);
-                       if (pset->flag & PE_DRAW_PART) {
-                               DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
-                       }
-                       else {
-                               DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
-                       }
+                       DEG_id_tag_update(&ob->id, DEG_TAG_SELECT_UPDATE);
                }
                else {
                        DEG_id_tag_update(&ob->id, OB_RECALC_DATA);