<p>Maybe you can try the the following code, I haven't used this for a while so usability is not guaranteed. Let's approach this in the most intuitive way (maybe there is some other API that can do the job but I simply can't recall). Essentially, you need to transform the position of each vertex, given translation, rotation and scaling factor. However, do not forget to transform the normal vector, tangents and bi-tangents (assume they are all in the same global coordinate frame). Note that the last field of tangents (and bitangents) should be preserved.</p>
<pre class="lang-csharp prettyprint-override"><code>using HelixToolkit.Wpf;

public void ApplyTransformationsToVertices(Mesh3D mesh) {
    Transform3DGroup transformGroup = new Transform3DGroup();       // translation, rotation, and scale all at once
    transformGroup.Children.Add(new TranslateTransform3D(mesh.Translation.ToVector3D())); // translation

    // I don't know a way to directly transform from Euler angle to Quaternion or Rotation Matrix 
    Quaternion rotationQuaternion = new QuaternionRotation3D(
        new Quaternion(new Vector3D(1, 0, 0), mesh.Rotation.X) *
        new Quaternion(new Vector3D(0, 1, 0), mesh.Rotation.Y) *
        new Quaternion(new Vector3D(0, 0, 1), mesh.Rotation.Z)
    );
    transformGroup.Children.Add(new RotateTransform3D(rotationQuaternion));     // rotation
    transformGroup.Children.Add(new ScaleTransform3D(mesh.Scale.ToVector3D())); // scale

    foreach (var vertex in mesh.Vertices) {
        Point3D vertexPosition = new Point3D(vertex.Position.X, vertex.Position.Y, vertex.Position.Z);

        // transform vertex position
        Point3D transformedVertexPosition = transformGroup.Transform(vertexPosition);
        vertex.Position = transformedVertexPosition.ToVector3();

        // transform normals
        vertex.Normal = TransformVector3d(vertex.Normal, rotationQuaternion);

        // transform tangents (the w field is not accounted for)
        for (int i = 0; i &lt; vertex.Tangents.Count; i++) {
            vertex.Tangents[i] = TransformVector3d(vertex.Tangents[i], rotationQuaternion);
        }

        // transform bi-tangents (the w field is not accounted for)
        vertex.Bitangent = TransformVector3d(vertex.Bitangent, rotationQuaternion);
    }
}

public Vector3 TransformVector3d(Vector3 vector, Quaternion rotationQuaternion) {
    Vector3D vector3D = new Vector3D(vector.X, vector.Y, vector.Z);
    Vector3D rotatedVector3D = rotationQuaternion.Rotate(vector3D);
    return new Vector3((float)rotatedVector3D.X, (float)rotatedVector3D.Y, (float)rotatedVector3D.Z);
}

public Vector3 TransformVector4d(Vector4 vector, Quaternion rotationQuaternion) {
    Vector3 vector3 = new Vector3(vector.X, vector.Y, vector.Z);        // extract
    Vector3D vector3D = new Vector3D(vector3.X, vector3.Y, vector3.Z);
    Vector3D rotatedVector3D = rotationQuaternion.Rotate(vector3D);
    return new Vector4((float)rotatedVector3D.X, (float)rotatedVector3D.Y, (float)rotatedVector3D.Z, vector.W);
}
<span class="math-container">```</span>
</code></pre>

CC BY-SA 4.0
2024-02-25T21:13:26.477Z
thanks for replaying. but i cant find Quaternion.Rotate in the sharpdx / Numerics /media3d namespaces
ahmed moussa
CC BY-SA 4.0
2024-02-25T14:44:48.227Z
2024-02-25T14:44:48.227Z
Enigmatisms
<p>I have This 3D mesh class ,
I use helixToolKit SharpDX to display the mesh and transformations ,
but i want to apply these transformations to the vertcies dirctly so the mesh can be exported with these transformations .
how to do that ?</p>
<pre><code>    using HelixToolkit.SharpDX.Core;
using SharpDX;
using System.Windows.Media.Media3D;

public class Vertex
{
    public Vector3 Position { get; set; }
    public Vector3 Normal { get; set; }
    public int NormalW { get; set; }
    public List&lt;Vector3&gt; UVs { get; set; }
    public List&lt;Vector4&gt; Tangents { get; set; }
    public Vector4 Bitangent { get; set; }
    public List&lt;VertexColor&gt; Colors { get; set; }
}

 public class Mesh
 {

    public Vector3 Translation { get; set; }

    public Vector3 Rotation { get; set; } //radian values of Euler angels

    public Vector3 Scale { get; set; }

    public List&lt;Vertex&gt; Vertices { get; set; }

    public List&lt;int&gt; Indices { get; set; }
    
    public Transform3D Transform
    {
        get =&gt; new MatrixTransform3D(this.GetTransformMatrix().ToMatrix3D());
    }


 }
</code></pre>
<p>Following Enigmatisms answer and using SharpDX Namespace</p>
<p>it should be something like this</p>
<pre><code>public static void ApplyTransformations(this MeshNodeViewModel mesh)
  {
      //Obtain the total transformations
      var tm = SharpMatrix.Translation(mesh.Translation);
      var sm = SharpMatrix.Scaling(mesh.Scale);
      var rxm = SharpMatrix.RotationX(mesh.Rotation.X);
      var rym = SharpMatrix.RotationY(mesh.Rotation.Y);
      var rzm = SharpMatrix.RotationZ(mesh.Rotation.Z);
      // Apply the transformations in the SRT order
      var transformations = sm * (rxm * (rzm * (rym * tm)));

      //Obtain the total rotations
      SharpQuaternion rotationQuaternion = SharpQuaternion.RotationMatrix(rxm * rzm * rym);

      List&lt;MyVertex&gt; vertices = new List&lt;MyVertex&gt;(mesh.Vertices);
      foreach (var vertex in vertices)
      {
          // transform vertex position
          SharpVector3 pos = vertex.Position;
          SharpVector3.Transform(ref pos, ref transformations, out SharpVector3 newPos);

          vertex.Position = newPos;

          // transform normals
          vertex.Normal = TransformVector3(vertex.Normal, rotationQuaternion);

          // transform tangents (the w field is not accounted for)
          for (int i = 0; i &lt; vertex.Tangents.Count; i++)
          {
              vertex.Tangents[i] = TransformVector4(
                      vertex.Tangents[i].ToSharp4(),
                      rotationQuaternion
                  )
                  .ToNumerics();
          }

          // transform bi-tangents (the w field is not accounted for)
          vertex.Bitangent = TransformVector4(vertex.Bitangent.ToSharp4(), rotationQuaternion)
              .ToNumerics();
      }

      mesh.Vertices = vertices;
      //Clear Transformations
      mesh.Translation = SharpVector3.Zero;
      mesh.Rotation = SharpVector3.Zero;
      mesh.Scale = SharpVector3.One;
  }

  public static SharpVector3 TransformVector3(
      SharpVector3 vector,
      SharpQuaternion rotationQuaternion
  )
  {
      Vector3D vector3D = new Vector3D(vector.X, vector.Y, vector.Z);
      SharpVector3.Transform(
          ref vector,
          ref rotationQuaternion,
          out SharpVector3 rotatedVector3D
      );
      return new SharpVector3(
          (float)rotatedVector3D.X,
          (float)rotatedVector3D.Y,
          (float)rotatedVector3D.Z
      );
  }

  public static SharpVector4 TransformVector4(
      SharpVector4 vector,
      SharpQuaternion rotationQuaternion
  )
  {
      SharpVector3 vector3 = new SharpVector3(vector.X, vector.Y, vector.Z); // extract
      SharpVector3.Transform(
          ref vector3,
          ref rotationQuaternion,
          out SharpVector3 rotatedVector3D
      );
      return new SharpVector4(
          (float)rotatedVector3D.X,
          (float)rotatedVector3D.Y,
          (float)rotatedVector3D.Z,
          vector.W
      );
  }
</code></pre>
<p>however the normals/Light reflection would change a little after appling the transformations,
But this will only happens if a scale is applied .
Is this supposed to happen ?</p>
<p>before
<a href="https://i.sstatic.net/RWHt6.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/RWHt6.png" alt="enter image description here" /></a>
after
<a href="https://i.sstatic.net/cxiJu.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/cxiJu.png" alt="enter image description here" /></a></p>
<p>or as gif
<a href="https://i.sstatic.net/PbKiW.gif" rel="nofollow noreferrer"><img src="https://i.sstatic.net/PbKiW.gif" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2024-02-26T02:00:10.483Z
Ok, I omitted one thing, I didn't notice that your `Scale` is of type `Vector3`. For uniform scaling, we can only apply rotation to the normal, tangents and bitangents, yet if is scaling is non-uniform, all these fields can't just be transformed by rotation. See [this article](https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/transforming-normals.html) for how to resolve this problem.
Enigmatisms
<3d><transformations><c#>
How apply 3d transformations on 3d Mesh vertcies
ahmed moussa
# How apply 3d transformations on 3d Mesh vertcies

(Asked by: username_0 on 2024-02-25)

I have This 3D mesh class ,
I use helixToolKit SharpDX to display the mesh and transformations ,
but i want to apply these transformations to the vertcies dirctly so the mesh can be exported with these transformations .
how to do that ?

```
    using HelixToolkit.SharpDX.Core;
using SharpDX;
using System.Windows.Media.Media3D;

public class Vertex
{
    public Vector3 Position { get; set; }
    public Vector3 Normal { get; set; }
    public int NormalW { get; set; }
    public List<Vector3> UVs { get; set; }
    public List<Vector4> Tangents { get; set; }
    public Vector4 Bitangent { get; set; }
    public List<VertexColor> Colors { get; set; }
}

 public class Mesh
 {

    public Vector3 Translation { get; set; }

    public Vector3 Rotation { get; set; } //radian values of Euler angels

    public Vector3 Scale { get; set; }

    public List<Vertex> Vertices { get; set; }

    public List<int> Indices { get; set; }
    
    public Transform3D Transform
    {
        get => new MatrixTransform3D(this.GetTransformMatrix().ToMatrix3D());
    }

 }

```

Following username_1 answer and using SharpDX Namespace

it should be something like this

```
public static void ApplyTransformations(this MeshNodeViewModel mesh)
  {
      //Obtain the total transformations
      var tm = SharpMatrix.Translation(mesh.Translation);
      var sm = SharpMatrix.Scaling(mesh.Scale);
      var rxm = SharpMatrix.RotationX(mesh.Rotation.X);
      var rym = SharpMatrix.RotationY(mesh.Rotation.Y);
      var rzm = SharpMatrix.RotationZ(mesh.Rotation.Z);
      // Apply the transformations in the SRT order
      var transformations = sm * (rxm * (rzm * (rym * tm)));

      //Obtain the total rotations
      SharpQuaternion rotationQuaternion = SharpQuaternion.RotationMatrix(rxm * rzm * rym);

      List<MyVertex> vertices = new List<MyVertex>(mesh.Vertices);
      foreach (var vertex in vertices)
      {
          // transform vertex position
          SharpVector3 pos = vertex.Position;
          SharpVector3.Transform(ref pos, ref transformations, out SharpVector3 newPos);

          vertex.Position = newPos;

          // transform normals
          vertex.Normal = TransformVector3(vertex.Normal, rotationQuaternion);

          // transform tangents (the w field is not accounted for)
          for (int i = 0; i < vertex.Tangents.Count; i++)
          {
              vertex.Tangents[i] = TransformVector4(
                      vertex.Tangents[i].ToSharp4(),
                      rotationQuaternion
                  )
                  .ToNumerics();
          }

          // transform bi-tangents (the w field is not accounted for)
          vertex.Bitangent = TransformVector4(vertex.Bitangent.ToSharp4(), rotationQuaternion)
              .ToNumerics();
      }

      mesh.Vertices = vertices;
      //Clear Transformations
      mesh.Translation = SharpVector3.Zero;
      mesh.Rotation = SharpVector3.Zero;
      mesh.Scale = SharpVector3.One;
  }

  public static SharpVector3 TransformVector3(
      SharpVector3 vector,
      SharpQuaternion rotationQuaternion
  )
  {
      Vector3D vector3D = new Vector3D(vector.X, vector.Y, vector.Z);
      SharpVector3.Transform(
          ref vector,
          ref rotationQuaternion,
          out SharpVector3 rotatedVector3D
      );
      return new SharpVector3(
          (float)rotatedVector3D.X,
          (float)rotatedVector3D.Y,
          (float)rotatedVector3D.Z
      );
  }

  public static SharpVector4 TransformVector4(
      SharpVector4 vector,
      SharpQuaternion rotationQuaternion
  )
  {
      SharpVector3 vector3 = new SharpVector3(vector.X, vector.Y, vector.Z); // extract
      SharpVector3.Transform(
          ref vector3,
          ref rotationQuaternion,
          out SharpVector3 rotatedVector3D
      );
      return new SharpVector4(
          (float)rotatedVector3D.X,
          (float)rotatedVector3D.Y,
          (float)rotatedVector3D.Z,
          vector.W
      );
  }

```

however the normals/Light reflection would change a little after appling the transformations,
But this will only happens if a scale is applied .
Is this supposed to happen ?

before
[![enter image description here](https://i.sstatic.net/RWHt6.png)](https://i.sstatic.net/RWHt6.png)
after
[![enter image description here](https://i.sstatic.net/cxiJu.png)](https://i.sstatic.net/cxiJu.png)

or as gif
[![enter image description here](https://i.sstatic.net/PbKiW.gif)](https://i.sstatic.net/PbKiW.gif)

**Tags:** 3d, transformations, c#

> **Comments:**
> **username_1**: Ok, I omitted one thing, I didn't notice that your `Scale` is of type `Vector3`. For uniform scaling, we can only apply rotation to the normal, tangents and bitangents, yet if is scaling is non-uniform, all these fields can't just be transformed by rotation. See [this article](https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/transforming-normals.html) for how to resolve this problem.  

---

## 1 answers

### Answer by username_1 on 2024-02-25. Score: 0

Maybe you can try the the following code, I haven't used this for a while so usability is not guaranteed. Let's approach this in the most intuitive way (maybe there is some other API that can do the job but I simply can't recall). Essentially, you need to transform the position of each vertex, given translation, rotation and scaling factor. However, do not forget to transform the normal vector, tangents and bi-tangents (assume they are all in the same global coordinate frame). Note that the last field of tangents (and bitangents) should be preserved.

```csharp
using HelixToolkit.Wpf;

public void ApplyTransformationsToVertices(Mesh3D mesh) {
    Transform3DGroup transformGroup = new Transform3DGroup();       // translation, rotation, and scale all at once
    transformGroup.Children.Add(new TranslateTransform3D(mesh.Translation.ToVector3D())); // translation

    // I don't know a way to directly transform from Euler angle to Quaternion or Rotation Matrix 
    Quaternion rotationQuaternion = new QuaternionRotation3D(
        new Quaternion(new Vector3D(1, 0, 0), mesh.Rotation.X) *
        new Quaternion(new Vector3D(0, 1, 0), mesh.Rotation.Y) *
        new Quaternion(new Vector3D(0, 0, 1), mesh.Rotation.Z)
    );
    transformGroup.Children.Add(new RotateTransform3D(rotationQuaternion));     // rotation
    transformGroup.Children.Add(new ScaleTransform3D(mesh.Scale.ToVector3D())); // scale

    foreach (var vertex in mesh.Vertices) {
        Point3D vertexPosition = new Point3D(vertex.Position.X, vertex.Position.Y, vertex.Position.Z);

        // transform vertex position
        Point3D transformedVertexPosition = transformGroup.Transform(vertexPosition);
        vertex.Position = transformedVertexPosition.ToVector3();

        // transform normals
        vertex.Normal = TransformVector3d(vertex.Normal, rotationQuaternion);

        // transform tangents (the w field is not accounted for)
        for (int i = 0; i < vertex.Tangents.Count; i++) {
            vertex.Tangents[i] = TransformVector3d(vertex.Tangents[i], rotationQuaternion);
        }

        // transform bi-tangents (the w field is not accounted for)
        vertex.Bitangent = TransformVector3d(vertex.Bitangent, rotationQuaternion);
    }
}

public Vector3 TransformVector3d(Vector3 vector, Quaternion rotationQuaternion) {
    Vector3D vector3D = new Vector3D(vector.X, vector.Y, vector.Z);
    Vector3D rotatedVector3D = rotationQuaternion.Rotate(vector3D);
    return new Vector3((float)rotatedVector3D.X, (float)rotatedVector3D.Y, (float)rotatedVector3D.Z);
}

public Vector3 TransformVector4d(Vector4 vector, Quaternion rotationQuaternion) {
    Vector3 vector3 = new Vector3(vector.X, vector.Y, vector.Z);        // extract
    Vector3D vector3D = new Vector3D(vector3.X, vector3.Y, vector3.Z);
    Vector3D rotatedVector3D = rotationQuaternion.Rotate(vector3D);
    return new Vector4((float)rotatedVector3D.X, (float)rotatedVector3D.Y, (float)rotatedVector3D.Z, vector.W);
}
```

```

> **Comments:**
> **username_0**: thanks for replaying. but i cant find Quaternion.Rotate in the sharpdx / Numerics /media3d namespaces  

---

