ConvSDF

SmoothParticleNets

Description

The ConvSDF layer is the other primary layer in addition to the ConvSP layer. ConvSDF stands for Signed Distance Field Convolution. The purpose of this layer is to enable particle-object interactions. The particles are represented as a list of coordinate locations. The objects are represented as signed distance fields (SDFs). SDFs are functions that take in a point in space relative to the object and return the signed distance to the closest point on the surface of the object, where the sign indicates if the query point is inside the object (negative) or outside (positive). For ConvSDF, this function is represented as a lookup table in the form of a grid. ConvSDF accepts a grid with the SDF values for each grid cell filled in, then performs linear interpolation when looking up the SDF value for a specific point.

ConvSDF works as follows. ConvSDF operates on sets of query locations, but for simplicity the following describes a single query location. For a given query point, ConvSDF places a convolutional kernel around that point’s location in space. Then it looks up the SDF values at the center of each of the kernel cells. This is then convolved with a set of weights in the same manner as a standard convolutional layer, the values are multiplied by a set of weights and then summed. The following diagram illustrates this process.

The SDF field is shown as a heatmap, with the object boundry shown in black. The large red dot is the query location, with the smaller red dots showing the kernel cell centers. The output of ConvSDF is the convolved value for the given query location.

The ConvSDF layer is given the pre-computed SDF grids; it does not compute grids from mesh files. That must be done externally. SmoothParticleNets does not include any tools to do this (although some can be found by searching online). This was done intentnionally to reduce the dependencies that this library requires. Furthermore, for simplicity, ConvSDF assumes the origin of all the SDF grids is the bottom corner grid. Ensure that when generating SDF grids that you note if the origin in the mesh file differs from the bottom corner of the grid and ensure you update all poses to take this into account. SDFs in 1D or in 4+D are not really well-defined, so for now ConvSDF only supports 2D or 3D.

One common usecase for ConvSDF is to compute when particles are inside objects and how to move them away from the object. This can be done by using ConvSDF to first compute which particles have a negative SDF value, and then by using another ConvSDF layer with fixed +1/-1 weights to compute numerical gradients. Multiplying the gradients by the distance yields the vector to move the particle by.

ConvSDF is implemented as a subclass of torch.nn.Module. This allows it to be used in the same manner as any other PyTorch layer (e.g., conv2d). ConvSDF is implemented with gradients for the query locations and the object poses so that it can be used during a backward call. ConvSdf is impelemented in native code with Cuda support, so it can be evaluated efficiently.

Example

Assume locs is a BxNxD tensor containing the locations of N D-dimensional particles across B batches.

# Let's make a simple SDF grid.
sdf = torch.Tensor([[0.7, 0.5, 0.5, 0.7], [0.5, -0.5, -0.5, 0.5], [-0.5, 0.5, 0.5, -0.5], [0.7, 0.5, 0.5, 0.7]])
# Construct a ConvSDF layer with 5 kernels.
ConvSDF(sdfs=[sdf], sdf_sizes=[1.0], out_channels=5, ndim=2, kernel_size=1, dilation=0.1, max_distance=1.0, with_params=True, compute_pose_grads=True)
# Convolve at the particle locations. Put the object at the origin with no rotation.
new_data = conv(locs, torch.Tensor([[0]]*locs.shape[0]), torch.Tensor([[0.0, 0.0, 0.0, 0.0]]*locs.shape[0]), torch.Tensor([[1.0]]*locs.shape[0]))

Documentation

ConvSDF provides three functions: a constructor, SetSDFs, and forward. Forward is called by calling the layer object itself (in the same manner as any standard PyTorch layer).