Page MenuHome

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

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) lowered the priority of this task from 90 to 50.

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 50 to 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.

Hi,
Using blender 2.91 and experiencing the same problem. Is the hair reset thing fixed?

A manual brush-stroke before toggling out of particle mode still seems to be necessary to keep the updated hair structure through a python script.
If done without the stroke, the hair structure is lost.

Is possible that the issue got re-introduced, as the particle system is a very fragile area.
Can you reproduce the issue with the steps and file from this report?

Adding necessary files to reproduce the error. In the .py file's last line, toggling out of particle mode does the hair reset. If 102 line is commented, the hair structure is preserved but no cache is generated until a manual stroke is done.

Running the alpha_test.py with all other attached files in the working directory reproduces the issue.

I just tested original script from first post and it works ok (except api change for bpy.ops.particle.brush_edit , but cache is generated correctly)

I don't know what I am doing wrong. From the original script also, I keep on getting poll errors on brush_edit.

Is the hair reset issue is generated in the attached example (alpha_test) by running:

blender --python alpha_test.py

Please verify

If the initial report works fine, please submit a new bug report.

@Sergey Sharybin (sergey) Hi, I tested script of first post in Blender 3.1 and it raised one poll error as well. Is there any chance this error could be fixed again? I simply just want to find a way to write hairkey.co.

Anyway, I solved this comb cache problem by adjusting hair using this line of code:

ob.particle_systems[0].particles[0].hair_keys[0].co_object_set(ob, ob.modifiers[0], ob.particle_systems[0].particles[0], mathutils.Vector((0, 0, 0)))

Now I can change co as I wanted.