Page MenuHome

Can't generate particle hair edit 'comb cache' in blender 2.8
Closed, ResolvedPublic

Description

System Information
Operating system: Windows-10-10.0.17134 64 Bits
Graphics card: GeForce GTX 660/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 416.94

Blender Version
Broken: version: 2.80 (sub 69), branch: blender2.7, commit date: 2019-05-17 23:36, hash: rB03672e77836d
Worked: blender 2.79

Short description of error
Can't generate particle hair edit data with simple script that goes into particle -edimode, and generates one brush stroke (worked in 2.79):

bpy.ops.particle.particle_edit_toggle()
# do 'empty' stroke to generate combing cache
bpy.ops.particle.brush_edit( 
stroke=[{"name": "", "location": (0, 0, 0), "mouse": (11, 11), "pressure": 0, "size": 0, "pen_flip": False, "time": 0, "is_start": False},
             {"name": "", "location": (0, 0, 0), "mouse": (12, 12), "pressure": 0, "size": 0, "pen_flip": False, "time": 0, "is_start": False}])
bpy.ops.particle.particle_edit_toggle()

Cache is not generate. Poll error is thrown, but same steps work if executed manually.


Exact steps for others to reproduce the error

  1. Open blend file:
  2. Run script, then execute new operator (in 3d view) with spacebar -> simple operator.
  3. Blender gives error: bpy.ops.particle.brush_edit.poll(). But user can comb hair fine, no poll error, and editmode hair cache is created ok. Only python way of generating cache fails. (I do not think python devs can generate 'groom cache' the way it is now)

Event Timeline

After digging bit more.
bpy.ops.particle.brush_edit() -this can generate particle edit cache ok if we are already in particle mode.
The problem is that if we are in obj mode, and in script switch to particle_edit_toggle() ('Particle') mode, then particle.brush_edit poll fails. I tried to call despgraph.update() before particle.brush_edit but it dosen't help.

Philipp Oeser (lichtwerk) triaged this task as Confirmed, Medium priority.

Can confirm, while polling (PE_poll, pe_get_current), psys->edit is NULL

Some findings:

  • It seems it is set up correctly in the modeswitch (particle_edit_toggle_exec):
  • edit = PE_create_current(depsgraph, scene, ob);
  • PE_create_particle_edit will also assign it to the psys: psys->edit = edit;
  • but somehow lost inbetween the particle_edit_toggle_exec and the call to bpy.ops.particle.brush_edit

(not sure if this is all relevant and not sure how much of a temporary data psys->edit really is, this might all work as expected and bug might be somewhere else...)

@Sergey Sharybin (sergey): mind checking?

@Clément Foucault (fclem), team work time!

Part of the issue is that particle system is wrongly tagged for recalc. Caused by a mistake in runtime field initialization. Can be fixed by

1diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
2index 02d477b1bde..03b6e48600d 100644
3--- a/source/blender/modifiers/intern/MOD_particlesystem.c
4+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
5@@ -186,11 +186,12 @@ static void deformVerts(ModifierData *md,
6 runtime->mesh_final->totedge != runtime->totdmedge ||
7 runtime->mesh_final->totface != runtime->totdmface)) {
8 psys->recalc |= ID_RECALC_PSYS_RESET;
9- runtime->totdmvert = runtime->mesh_final->totvert;
10- runtime->totdmedge = runtime->mesh_final->totedge;
11- runtime->totdmface = runtime->mesh_final->totface;
12 }
13
14+ runtime->totdmvert = runtime->mesh_final->totvert;
15+ runtime->totdmedge = runtime->mesh_final->totedge;
16+ runtime->totdmface = runtime->mesh_final->totface;
17+
18 if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
19 struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
20 psmd->flag &= ~eParticleSystemFlag_psys_updated;

However, after this is fixed i've got crash in depth drawing. Seems that DRW_draw_depth_object() expects mesh batch cache to be already allocated. However, this is not the case here: the object is tagged for geometry update when toggling particle edit mode. I guess is is where batch cache gets removed.

Operator works fine because viewport is drawn prior to stroke and that ensures all needed batch caches.

Clément Foucault (fclem) raised the priority of this task from Confirmed, Medium to Confirmed, High.Jun 28 2019, 12:33 PM

@Sergey Sharybin (sergey) Can you still reproduce the crash? I can't reproduce it even if I checkout the original broken commit. I did test with and without your fix but it does not change the outcome of the operator poll function.

I tried with a debug build with and without asan.

@Clément Foucault (fclem), ugh, it was relying on rB36faf739a71 which caused some issues and needs re-consideration.

For this specific case i think you can safely use P1018 (just don't commit it). If you can solve the crash, i can then solve the issue with unintended hair reset.

Thanks! Will have a look into solving the unwanted hair reset.

Just to be clear, I do not really care about hair combing error when switching from object mode - to particle edit mode. I just wish there was way to generate particle hair 'comb cache', so that later I can write hair_key.co to it. Maybe it would be easier to make new operator for generatig particle comb cache ?

Well, this is a tricky call. In this case it seems it's easy to fix this particular case, especially since it's technically regression compared to 2.79. I do have D5162 which i will commit in a bit.