Tutorial: Hair Card Generator

Hi Mark,

Thanks for the recommendations.
I checked and indeed libomp140.dll is missing both in the system and in the UE installation folder.
I downloaded (from https://www.dllme.com/dll/files/libomp140_x86_64) and installed (copied) the library to the system.
After that, the project loaded without errors in the log and the plugin eventually started. I have not yet checked how correctly it works.
By the way, I am not using Windows 11, but Windows 10 x64 Pro.
Thanks again for helping me solve this problem.

Best regards,
Vit

I get this error when trying to use the generator, any ideas?

LogPython: [StrandCardAllocator] Feature generation…
LogPython: [StrandCardAllocator] Clustering features…
LogScript: Error: Script Msg: Traceback (most recent call last):
File “C:\Program Files/Epic Games/UE_5.6/Engine/Plugins/Experimental/HairCardGenerator/Content/Python\CardUEInterop_init_.py”, line 34, in generate_clumps
return self._wrapped_inst.generate_clumps(settings_group_index)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: HairCardGenController: Traceback (most recent call last):
File “C:\Program Files/Epic Games/UE_5.6/Engine/Plugins/Experimental/HairCardGenerator/Content/Python\CardUEInterop\ue_card_gen_controller.py”, line 177, in generate_clumps
labels, max_main_clump = clump_gen.cluster_strands(target_num_clumps=group_settings.num_clumps,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Program Files/Epic Games/UE_5.6/Engine/Plugins/Experimental/HairCardGenerator/Content/Python\Modules\Geometry\cluster\clump_generator.py”, line 62, in cluster_strands
labels_local, max_main_clump = self._strand_allocator.allocate(target_num_clumps,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Program Files/Epic Games/UE_5.6/Engine/Plugins/Experimental/HairCardGenerator/Content/Python\Modules\Geometry\cluster\strand_card_allocation.py”, line 144, in allocate
ind_closest_strand = pairwise_distances(point_features[mask], point_features[np.logical_not(mask)]).argmin(axis=-1)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Alex\Documents\Unreal Projects\RigorMortis\Intermediate\PipInstall\Lib\site-packages\sklearn\metrics\pairwise.py”, line 2039, in pairwise_distances
return _parallel_pairwise(X, Y, func, n_jobs, **kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Alex\Documents\Unreal Projects\RigorMortis\Intermediate\PipInstall\Lib\site-packages\sklearn\metrics\pairwise.py”, line 1579, in _parallel_pairwise
return func(X, Y, **kwds)
^^^^^^^^^^^^^^^^^^
File “C:\Users\Alex\Documents\Unreal Projects\RigorMortis\Intermediate\PipInstall\Lib\site-packages\sklearn\metrics\pairwise.py”, line 300, in euclidean_distances
X, Y = check_pairwise_arrays(X, Y)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Alex\Documents\Unreal Projects\RigorMortis\Intermediate\PipInstall\Lib\site-packages\sklearn\metrics\pairwise.py”, line 163, in check_pairwise_arrays
Y = check_array(
^^^^^^^^^^^^
File “C:\Users\Alex\Documents\Unreal Projects\RigorMortis\Intermediate\PipInstall\Lib\site-packages\sklearn\utils\validation.py”, line 931, in check_array
raise ValueError(
ValueError: Found array with 0 sample(s) (shape=(0, 24)) while a minimum of 1 is required by check_pairwise_arrays.
LogScript: Error: Script call stack:
/HairCardGenerator/Python/CardUEInterop/__init___PY.HairCardGenForwardingController.GenerateClumps
LogHairCardGenerator: Error: Strand clustering failed for settings group 0. Check the log for details.
LogHairCardGenerator: Error: Failed to generate cards for all groups. See log for details.

Hmmm, this is an edge case we I don’t think we’ve encoutered. In essence the max flyaways allowed and detected is larger than or equal to the number of strands in the card group. This means we’re trying to make every strand into its own card and that’s a code path that doesn’t work correctly. I will put a ticket in to fix this case.

You should be able to work around it by lowering the Max Flyaways setting

1 Like

For whatever reason I had to set Max Flyaways to 0 for the generator to work, besides that it seems to be functional now.

What engine version are you using? The Max Flyaways = 0, should be a special case that skips flyaway detection entirely and you should not end up in the code path you did, this was in as of UE 5.5.

If you’re at or past 5.5, please let me know as I should investigate that scenario further.

Thanks

1 Like

I’m using UE 5.6.1

Hi @mark-winter ,
Thank you for your tutorial. I have a problem with this section (image). I used the Groom Exporter tool for Maya provided by Epic, but after importing, I can’t separate my hair into groups.
Thank you.

Hi @Lan_Ngo

Getting card groups out of maya in the way the hair card generator expects is a bit difficult. The artists here use a bunch of internal Houdini tooling for that and Maya doesn’t seem to want to export in the same way.

Check out this previous answer, it seemed to work for the OP in that case. You can check their post above for a screenshot and the initial property update code they were using as well.

1 Like

Thanks @papa335678 I’ll look into this

I have the same problem UE 5.5.4 LogHairCardGenerator: Error: Failed to find an active hair card controller.
LogHairCardGenerator: Error: No hair card generator controller found, cannot generate hair cards!