Drawing simple custom geometries (basic usage of GeometryMesh)

I am trying to modify the MultiThreadingSample.xaml.cs to draw other custom geometries. To minimize code changes I just change this:

       public static SceneNode CreateBoxSceneNodes(MeshGeometry3D mesh, Point3D center, Size3D size, float modelScaleFactor, bool useSingleColor, int xCount, int yCount, int zCount)
           var rootSceneNode = new SceneNode();

           var dxMeshGeometry3D = new GeometryMesh(
               new List<Vector3>() { new Vector3(1,1,0),
                   new Vector3(1,-1,0),
                   new Vector3(-1,1,0),
                   new Vector3(-1,-1,0),
                   new Vector3(0,0,1),
               new List<Vector3>() { },
               new List<Vector2>(),
               new List<int>() { 0, 1, 3, 1, 2, 3, 0, 4, 3, 2, 3, 4, 2, 4, 1, 1, 0, 4 });

That is to draw a Pyramid with square base. I also tried something even simpler, just a flat triangle:

var dxMeshGeometry3D = new GeometryMesh(
                new List<Vector3>() {
                    new Vector3(0,1,0),
                    new Vector3(1,0,0),
                    new Vector3(1,1,0)
                new List<Vector3>() {
                    new Vector3(0,0,1),
                    new Vector3(0,0,1),
                    new Vector3(0,0,1)},
                new List<Vector2>(),
                new List<int>() { 0, 1, 2 });

But it does just not render any figure. The reason I am trying to do this is because I need to render advanced cad models (that assimp cannot load, so I load them aside and get the list of points and triangle indices). Also the normals are not usually available (I can compute them myself, but is there a method to do it, or do I always need to create the geometry mesh with the normals per point?).

Moreover, I do not need to apply any texture onto the models (just solid colors) can I leave the texture indices list empty?

Just add that I do not want to use the WPF models since I need to render all in the DXEngine (so avoiding the conversion from wpf 3d models to DXEngine objects).

Thanks for the support.
You are using some custom MeshGeomtry objects so I cannot test this code, but I would say that you probably need to inverse the order of triangle indices. The order of triangle indices determines which side of the triangle is front side and which side is back side. Usually counter-clockwise side is front side.

This is described in the "Basic WPF objects tutorial" sample - the first sample in the Ab3d.PowerToys samples project.

For example in your case, the order of the following triangle indices "0, 1, 3, 1, 2, 3, ..." can be changed by swapping two items, for example swapping second and third: "0, 3, 1, 1, 3, 2, ...".

The best way to diagnose such problems is to set front material to green color and back material to red color - this way you will immediately see which triangles need to be swapped.

You can also use:

var mesh = new Ab3d.Meshes.PyramidMesh3D(bottomCenterPosition, size).Geometry;

and check how the mesh is created by this method (you can also use some other class from Ab3d.Meshes namespace).

To see a few samples on how to create low level DXEngine objects, please check the "ManuallyCreatedSceneNodes.xaml.cs" sample in the "DXEngine advanced" section of the Ab3d.DXEngine sample project.
Andrej Benedik
First of all thanks for the quick response!

I did not see the examples down below, you pointed me to the right direction.

Essentially the problem are the texture coordinates, I realized AB4D was throwing an exception:

Exception thrown: 'System.Exception' in Ab3d.DXEngine.dll ("TextureCoordinates count is not the same as positions count")

I guess, even if no texture is applied to the Mesh it still requires to have all the texture coordinates for each point (I am guessing that the Vertex definition on DirectX has the texture coordinates even if not used?).

Do you think there is a lot of overhead on that? Is it tunable? Just asking because the CADs usually do not have textures but just solid colors.
I see now that you should just pass null for the textureCoordinates parameter and not an empty array / list. If the textureCoordinates parameter is not null then the code compares its length to the number of positions.

I will update the code to prevent this exception in the case of empty array / list.

Btw., if you will need to generate texture coordinates, then you can use the methods in the Ab3d.Utilities.MeshUtils class: GeneratePlanarTextureCoordinates, GenerateCubicTextureCoordinates, GenerateCylindricalTextureCoordinates. See "TextureCoordinatesGeneratorSample" in the Utilities section of Ab3d.PowerToys samples for more info.
Andrej Benedik
Maybe you can just add it in the documentation that it can be null in the constructor, because when I don't see it specified I always go with empty lists, but that might be my default thinking for coding.

Forum Jump:

Users browsing this thread:
1 Guest(s)