Generic function that transforms matrix

My question is similar to: Generic Function that multiplies Matricies

I’m struggling to figure out what constraints I need to apply to my class to make it compile.

Roughly, the code looks like this:

#[derive(Debug)]
pub struct PointCloud<NaD>
where
    NaD: na::DimName,
{
    // The data structure that stores the points. Each point is a column in this matrix, so there
    // are as many columns as points.
    pub data: na::MatrixMN<f32, NaD, na::Dynamic>,
}

impl<NaD> PointCloud<NaD>
where
    NaD: na::DimName,
    na::DefaultAllocator: na::allocator::Allocator<f32, NaD>,
{
    pub fn transform(&self, transform: &na::Transform<f32, NaD, na::TGeneral>) -> PointCloud<NaD> {
        let homogenous_mat = self
            .data
            .clone()
            .insert_fixed_rows::<na::U1>(self.data.nrows(), 1.0);
        let transformed_mat = transform * homogenous_mat;
        PointCloud::<NaD>::from_data(
            transformed_mat.remove_fixed_rows::<na::U1>(transformed_mat.nrows()),
        )
    }
}

I’m still figuring out how this function should work, but the compiler error I’ve been stuck on for some time now is on the line that declares the transform method. I get this error currently:

   Compiling kuba v0.1.0 (/Users/kevin/src/rskgk/kuba)
error[E0277]: cannot add `typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>` to `<NaD as na::DimName>::Value`
  --> src/geom/point_cloud.rs:65:5
   |
65 | /     pub fn transform(&self, transform: &na::Transform<f32, NaD, na::TGeneral>) -> PointCloud<NaD> {
66 | |         //pub fn transform(&self, transform: &na::MatrixN<f32, NaD>) -> PointCloud<NaD> {
67 | |         let homogenous_mat = self
68 | |             .data
...  |
79 | |         //PointCloud::<NaD>::from_data(transformed_mat.remove_rows(self.data.nrows(), 1))
80 | |     }
   | |_____^ no implementation for `<NaD as na::DimName>::Value + typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>`
   |
   = help: the trait `std::ops::Add<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>>` is not implemented for `<NaD as na::DimName>::Value`
   = help: consider adding a `where <NaD as na::DimName>::Value: std::ops::Add<typenum::uint::UInt<typenum::uint::UTerm, typenum::bit::B1>>` bound
   = note: required because of the requirements on the impl of `na::DimNameAdd<na::U1>` for `NaD`

I tried adding na::DimNameAddna::U1 to the constraints for NaD, but then I get more errors that look like I’m going in the wrong direction.

Update:
I got it working for na::U3 only, with the following code:

impl PointCloud<na::U3> {
    // TODO(kgreenek): Make this generic on NaD and implement in the class above.
    pub fn transform(&self, transform: &na::MatrixN<f32, na::U4>) -> PointCloud<na::U3> {
        let homogeneous_mat = self
            .data
            .clone()
            .insert_fixed_rows::<na::U1>(self.data.nrows(), 1.0);
        let transformed_mat = transform * homogeneous_mat;
        let i = transformed_mat.nrows() - 1;
        PointCloud::<na::U3>::from_data(transformed_mat.remove_fixed_rows::<na::U1>(i))
    }
}

The idea is to make this generic for either 2d or 3d point clouds, so NaD can be either na::U2 or na::U3.