NVIDIA / warp

A Python framework for high performance GPU simulation and graphics

Home Page:https://nvidia.github.io/warp/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Alternative tetmesh format

honglin-c opened this issue · comments

Would it be possible to provide an example where the user reads a tetmesh from a .mesh file? Thank you! :)

I was using the following code (with libigl python binding) to load the tetmesh, which was unsuccessful so far.

  V, T, F = igl.read_mesh("./data/tetmesh/spot.mesh")

  V = Vt.Vec3fArray.FromNumpy(V)
  T = Vt.IntArray.FromNumpy(T)

  builder.add_soft_mesh(
      pos=wp.vec3(0.0, 2.0, 0.0),
      rot=wp.quat_identity(),
      scale=0.1,
      vel=wp.vec3(0.0, 0.0, 0.0),
      vertices=V, 
      indices=T, 
      density=100.0, 
      k_mu=2000.0, 
      k_lambda=2000.0, 
      k_damp=2.0,
      tri_ke=0.0,
      tri_ka=1e4,
      tri_kd=0.0,
      tri_drag=0.0,
      tri_lift=0.0,
  )

image

Hi @honglin-c, could you provide the .mesh file for this example so we can reproduce?

Thanks,
Miles

commented

I'm guessing it's this mesh: https://github.com/honglin-c/INSR-PDE/blob/main/elasticity/data/spot.mesh

download link: spot.zip

I tried writing a minimal reproducer with @honglin-c 's approach

import os
import math

import warp as wp
import warp.examples
import warp.sim
import warp.optim
import warp.sim.render

import igl
import scipy as sp
import numpy as np
from pxr import Usd, UsdGeom, Vt

wp.init()

# sim model
builder = wp.sim.ModelBuilder()

V, T, F = igl.read_mesh("/path/to/meshes/spot.mesh")

V = Vt.Vec3fArray.FromNumpy(V)
T = Vt.IntArray.FromNumpy(T)

builder.add_soft_mesh(
    pos=wp.vec3(0.0, 0.0, 0.0),
    rot=wp.quat_identity(),
    scale=2.0,
    vel=wp.vec3(0.0, 0.0, 0.0),
    vertices=V,
    indices=T,
    density=1.0,
    k_mu=2000.0,
    k_lambda=2000.0,
    k_damp=2.0,
    tri_ke=0.0,
    tri_ka=1e-8,
    tri_kd=0.0,
    tri_drag=0.0,
    tri_lift=0.0,
)

# finalize model
model = builder.finalize(requires_grad=False)

model.soft_contact_ke = 2.0e3
model.soft_contact_kd = 0.1
model.soft_contact_kf = 10.0
model.soft_contact_mu = 0.7

model.ground = True

state = model.state(requires_grad=False)

# rendering
renderer = wp.sim.render.SimRenderer(model, "spot.usd")

renderer.begin_frame(0)
renderer.render(state)
renderer.end_frame()

renderer.save()

and it seemed to work:
Screenshot from 2024-04-09 08-24-03

But I'm very new to using warp, so I might be doing something wrong!

Nice! Thank you @samuelpmish! @honglin-c does this solve your problem?

Wowww thank you so much @samuelpmish!! :)))

Nice! Thank you @samuelpmish! @honglin-c does this solve your problem?

Sort of but not fully 👀

Actually, I realized the problem was with the simulation and the scale of the tetmesh.

For instance, I will have this problem for the code below. But if I simply change scale=5.0 to scale=10.0 in the parameter list of builder.add_soft_mesh(), the simulation will run without problem.

Still trying to figure out what's going wrong here... 🤔

import math
import os

import warp as wp
import warp.sim
import warp.sim.render

import numpy as np
from pxr import Usd, UsdGeom, Vt

import igl

wp.init()

class Example:
    def __init__(self, stage):
        sim_fps = 60.0
        self.sim_substeps = 64
        sim_duration = 5.0
        self.sim_frames = int(sim_duration * sim_fps)
        self.frame_dt = 1.0 / sim_fps
        self.sim_dt = (1.0 / sim_fps) / self.sim_substeps
        self.sim_time = 0.0

        # bunny
        builder = wp.sim.ModelBuilder()

        V, T, F = igl.read_mesh("./data/tetmesh/spot.mesh")

        # don't know why warp needs this
        V = Vt.Vec3fArray.FromNumpy(V)
        T = Vt.IntArray.FromNumpy(T)

        builder.add_soft_mesh(
            pos=wp.vec3(0.0, 10.0, 0.0),
            rot=wp.quat_identity(),
            scale=5.0,
            vel=wp.vec3(0.0, 0.0, 0.0),
            vertices=V, 
            indices=T, 
            density=100.0, 
            k_mu=100000.0, 
            k_lambda=100000.0, 
            k_damp=2.0,
            tri_ke=0.0,
            tri_ka=1e4,
            tri_kd=0.0,
            tri_drag=0.0,
            tri_lift=0.0,
        )

        self.model = builder.finalize()
        self.model.ground = True

        self.model.soft_contact_ke = 2.0e3
        self.model.soft_contact_kd = 0.1
        self.model.soft_contact_kf = 10.0
        self.model.soft_contact_mu = 0.7

        self.integrator = wp.sim.SemiImplicitIntegrator()

        self.rest = self.model.state()

        self.state_0 = self.model.state()
        self.state_1 = self.model.state()

        self.volume = wp.zeros(1, dtype=wp.float32)

        self.renderer = None
        if stage:
            self.renderer = wp.sim.render.SimRenderer(self.model, stage)

        self.use_graph = wp.get_device().is_cuda
        if self.use_graph:
            with wp.ScopedCapture() as capture:
                self.simulate()
            self.graph = capture.graph

    def simulate(self):
        for _ in range(self.sim_substeps):
            self.state_0.clear_forces()
            # self.state_1.clear_forces()

            self.integrator.simulate(self.model, self.state_0, self.state_1, self.sim_dt)

            # swap states
            (self.state_0, self.state_1) = (self.state_1, self.state_0)

    def step(self):
        with wp.ScopedTimer("step"):
            if self.use_graph:
                wp.capture_launch(self.graph)
            else:
                self.simulate()

        self.sim_time += self.frame_dt

    def render(self):
        if self.renderer is None:
            return

        with wp.ScopedTimer("render"):
            self.renderer.begin_frame(self.sim_time)
            self.renderer.render(self.state_0)
            self.renderer.end_frame()


if __name__ == "__main__":
    stage_path = os.path.join(os.path.dirname(__file__), "outputs/example_soft_spot.usd")

    example = Example(stage_path)

    for i in range(example.sim_frames):
        example.step()
        example.render()

    if example.renderer:
        example.renderer.save()

This is with scale = 5.0:

image

Without the simulation (I commented out example.step()) , the rendering looks fine:

image

But if I simply change scale=5.0 to scale=10.0 in builder.add_soft_mesh(), the simulation just runs perfectly! :0

I'm having a mesh colliding with the ground and then bouncing back :

image image image

This is probably just a classic example of simulation stability being dependent on the scale, e.g.: by scaling everything down then everything gets lighter while stiffness is staying the same, i.e.: the problem got a lot stiffer, which means you need smaller time-steps to be stable.

If you are reducing scale you generally need to reduce the time-step size (dt) or take more substeps as well.

Cheers,
Miles

Thank you so much for the explanations! Now I finally understand. :)

Resolved by @samuelpmish