Closed PavelBlend closed 5 years ago
LevelSetLiquidSolver3 uses voxel grids to track fluid surface. More specifically, it uses SDF (or level set field) that is stored in a grid and moves it around via fluid velocity field which is also defined on grids.
In order to get the mesh, you need to call marchingCubes
to solver.signedDistanceField
.
I have all obj files have a size of 0 bytes. What am I doing wrong? level_set_test.zip
You also need to add emitter.addSignedDistanceTarget(solver.signedDistanceField)
after solver.emitter = emitter
. This let emitter to know which grid (among many grids in the solver) to emit volume in which form (SDF in this case). You also want to set margin
greater than 0.2. Below is part of the code I fixed:
# create emitter
mesh_obj = pyjet.TriangleMesh3()
mesh_obj.readObj(filename='emitter.obj')
emitter_mesh = pyjet.ImplicitTriangleMesh3(
mesh=mesh_obj,
resolutionX=solver.resolution.x,
margin=0.2
)
emitter = pyjet.VolumeGridEmitter3(
sourceRegion=emitter_mesh,
isOneShot=True
)
solver.emitter = emitter
emitter.addSignedDistanceTarget(solver.signedDistanceField)
# create collider
mesh_obj = pyjet.TriangleMesh3()
mesh_obj.readObj(filename='collider.obj')
collider_mesh = pyjet.ImplicitTriangleMesh3(
mesh=mesh_obj,
resolutionX=solver.resolution.x,
margin=0.2
)
collider = pyjet.RigidBodyCollider3(
surface=collider_mesh
)
solver.collider = collider
I'm having trouble again with level set solver. I create a mesh this way:
surface_mesh = pyjet.marchingCubes(
solver.signedDistanceField,
solver.gridSpacing,
(0, 0, 0),
0.0, 0, 0
)
But I get the wrong mesh size:
How to fix it?
Is Fluid mesh the result of marching cubes? Looks like the overall scale got doubled after the marching cubes. Can you share other parts of the code (like emitter creation) so ghat I can try reproducing it?
Is Fluid mesh the result of marching cubes?
yes
Can you share other parts of the code (like emitter creation)
triangle_mesh = pyjet.TriangleMesh3(
points=[[v.co.x, v.co.z, v.co.y] for v in mesh.vertices],
pointIndices=[[p.vertices[0], p.vertices[2], p.vertices[1]] for p in mesh.polygons]
)
imp_triangle_mesh = pyjet.ImplicitTriangleMesh3(
mesh=triangle_mesh,
resolutionX=int(round(
solver.resolution.x * obj.dimensions[0] / domain_object.dimensions[0],
0
)),
margin=0.2
)
...
emitter = pyjet.VolumeGridEmitter3(implicit_triangle_mesh, True)
emitter.addSignedDistanceTarget(solver.signedDistanceField)
transform = pyjet.Transform3(
translation=(pos[0], pos[2], pos[1]),
orientation=(-rot[0], rot[1], rot[3], rot[2])
)
emitter.sourceRegion.transform = transform
I tried to create a simple example but could not reproduce the error. This error only occurs in the blender. And I noticed that the mesh size depends on the resolution of the simulation. Here is an example with different resolutions: How to fix this behavior?
Looks like grid size is not changing when the resolution is changing. Seems like it's fixed. Can you double check?
Where should the grid size be indicated? Like this?:
grid_size = 0.04
solver = pyjet.LevelSetLiquidSolver3(
resolution=(50, 50, 50),
gridSpacing=grid_size,
gridOrigin=(0, 0, 0),
domainSizeX=2.0
)
Yes, exactly. Let me know if that doesn't work.
The grid size I set.
I check the grid size in this way:
print(solver.gridSpacing)
And the correct value is always displayed in the console. But the mesh size is not correct.
I added the code to the github: https://github.com/PavelBlend/blender_jet_fluids_addon/tree/level-set-solver
Maybe you find a mistake.
The level set simulation starts here: https://github.com/PavelBlend/blender_jet_fluids_addon/blob/level-set-solver/jet_fluids/bake_fluid.py#L86
Grid size calculation is here: https://github.com/PavelBlend/blender_jet_fluids_addon/blob/level-set-solver/jet_fluids/bake.py#L147
Thanks for the info! Let me take a look. Might take some time though.
I found my mistake. I multiply the coordinate of the mesh vertex by a factor: https://github.com/PavelBlend/blender_jet_fluids_addon/blob/level-set-solver/jet_fluids/bake_mesh.py#L71
Since simulation resolution and mesh resolution may vary. But I forgot about it. I apologize. The error was on my part.
I have one more problem.
I am trying to change the Level Set Solver this way:
solver.levelSetSolver = pyjet.FmmLevelSetSolver3()
And I get an error:
TypeError: pyjet.FmmLevelSetSolver3: No constructor defined!
Am I doing everything right? And why does this error occur?
Glad you found the problem!
Missing constructor seems to be the binding problem. Let me create a separate issue to track it.
In the PIC solver, particles act as a fluid. And what is the liquid in the solver LevelSetLiquidSolver3? How can I save fluid data (positions, velocities, forces) in a LevelSet solver? And how can you create a mesh, based on the LevelSet solver?