qbhf2's picture
added NvidiaWarp and GarmentCode repos
66c9c8a
raw
history blame
5.93 kB
# Copyright (c) 2022 NVIDIA CORPORATION. All rights reserved.
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto. Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
###########################################################################
# Example Sim Cloth
#
# Shows a simulation of an FEM cloth model colliding against a static
# rigid body mesh using the wp.sim.ModelBuilder().
#
###########################################################################
import argparse
import math
import os
from enum import Enum
import numpy as np
from pxr import Usd, UsdGeom
import warp as wp
import warp.sim
import warp.sim.render
wp.init()
class IntegratorType(Enum):
EULER = "euler"
XPBD = "xpbd"
def __str__(self):
return self.value
class Example:
def __init__(self, stage, integrator=IntegratorType.EULER):
self.device = wp.get_device()
self.integrator_type = integrator
self.sim_width = 64
self.sim_height = 32
self.sim_fps = 60.0
self.sim_substeps = 32
self.sim_duration = 5.0
self.sim_frames = int(self.sim_duration * self.sim_fps)
self.frame_dt = 1.0 / self.sim_fps
self.sim_dt = self.frame_dt / self.sim_substeps
self.sim_time = 0.0
self.sim_use_graph = wp.get_device().is_cuda
self.profiler = {}
builder = wp.sim.ModelBuilder()
if self.integrator_type == IntegratorType.EULER:
builder.add_cloth_grid(
pos=wp.vec3(0.0, 4.0, 0.0),
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), math.pi * 0.5),
vel=wp.vec3(0.0, 0.0, 0.0),
dim_x=self.sim_width,
dim_y=self.sim_height,
cell_x=0.1,
cell_y=0.1,
mass=0.1,
fix_left=True,
tri_ke=1.0e3,
tri_ka=1.0e3,
tri_kd=1.0e1,
)
else:
builder.add_cloth_grid(
pos=wp.vec3(0.0, 4.0, 0.0),
rot=wp.quat_from_axis_angle(wp.vec3(1.0, 0.0, 0.0), math.pi * 0.5),
vel=wp.vec3(0.0, 0.0, 0.0),
dim_x=self.sim_width,
dim_y=self.sim_height,
cell_x=0.1,
cell_y=0.1,
mass=0.1,
fix_left=True,
edge_ke=1.0e2,
add_springs=True,
spring_ke=1.0e3,
spring_kd=0.0,
)
usd_stage = Usd.Stage.Open(os.path.join(os.path.dirname(__file__), "assets/bunny.usd"))
usd_geom = UsdGeom.Mesh(usd_stage.GetPrimAtPath("/bunny/bunny"))
mesh_points = np.array(usd_geom.GetPointsAttr().Get())
mesh_indices = np.array(usd_geom.GetFaceVertexIndicesAttr().Get())
mesh = wp.sim.Mesh(mesh_points, mesh_indices)
builder.add_shape_mesh(
body=-1,
mesh=mesh,
pos=wp.vec3(1.0, 0.0, 1.0),
rot=wp.quat_from_axis_angle(wp.vec3(0.0, 1.0, 0.0), math.pi * 0.5),
scale=wp.vec3(2.0, 2.0, 2.0),
ke=1.0e2,
kd=1.0e2,
kf=1.0e1,
)
self.model = builder.finalize()
self.model.ground = True
self.model.soft_contact_ke = 1.0e4
self.model.soft_contact_kd = 1.0e2
if self.integrator_type == IntegratorType.EULER:
self.integrator = wp.sim.SemiImplicitIntegrator()
else:
self.integrator = wp.sim.XPBDIntegrator(iterations=1)
self.state_0 = self.model.state()
self.state_1 = self.model.state()
self.renderer = wp.sim.render.SimRenderer(self.model, stage, scaling=40.0)
self.graph = None
if self.sim_use_graph:
# create update graph
wp.capture_begin(self.device)
try:
self.update()
finally:
self.graph = wp.capture_end(self.device)
def update(self):
with wp.ScopedTimer("simulate", dict=self.profiler):
if self.sim_use_graph and self.graph:
wp.capture_launch(self.graph)
self.sim_time += self.frame_dt
else:
wp.sim.collide(self.model, self.state_0)
for _ in range(self.sim_substeps):
self.state_0.clear_forces()
self.integrator.simulate(self.model, self.state_0, self.state_1, self.sim_dt)
if not wp.get_device().is_capturing:
self.sim_time += self.sim_dt
# swap states
(self.state_0, self.state_1) = (self.state_1, self.state_0)
def render(self, is_live=False):
with wp.ScopedTimer("render", active=True):
time = 0.0 if is_live else self.sim_time
self.renderer.begin_frame(time)
self.renderer.render(self.state_0)
self.renderer.end_frame()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument(
"--integrator",
help="Type of integrator",
type=IntegratorType,
choices=list(IntegratorType),
default=IntegratorType.EULER,
)
args = parser.parse_args()
stage_path = os.path.join(os.path.dirname(__file__), "outputs/example_sim_cloth.usd")
example = Example(stage_path, integrator=args.integrator)
for i in range(example.sim_frames):
example.update()
example.render()
frame_times = example.profiler["simulate"]
print("\nAverage frame sim time: {:.2f} ms".format(sum(frame_times) / len(frame_times)))
example.renderer.save()