AB4D Forum

Full Version: Obtaining instance meshes from InstancedMeshGeometryVisual3D
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
We are using InstancedMeshGeometryVisual3D to display large number of Spheres. 

These create Instanced Meshobjectnodes – in the context of exporting these via Assimp, how would we go about obtaining individual meshes for every point? Or is this something we would manually have to re-create when we generate our Model3D using InstanceData[]?
As written in the previous post, you need to convert ObjectNode objects into WPF's GeometryModel3D objects to be able to export them by AssimpWpfExporter.

This means that you will need to generate a Model3DGroup with many GeometryModel3D objects - each GeometryModel3D would be created from each InstanceData from the InstancedMeshGeometryVisual3D - those objects will need to use the same MeshGeometry and have its own material (based on the color from InstanceData) and have their own MatrixTransform3D (based on World matrix from InstranceData).

The following methods can be used to do that (the code need to be adjusted slightly because it is taken from InstancedMeshGeometryVisual3D where it is need to generate WPF 3D objects in case WPF hit testing is used - when InstancedMeshGeometryVisual3D.IsWpfHitTestVisible is set to true):

       private Model3DGroup GenerateModel3DGroup()
           var instancesData = InstancesData;

           if (instancesData == null)
               return null;

           var model3DGroup = new Model3DGroup();

           var count = instancesData.Length;

           for (var i = 0; i < count; i++)
               var wpfGeometryModel3D = GenerateWpfGeometryModel3D(ref instancesData[i]);

               // Set our own InstanceIndexProperty to the index of this instance.
               // This way we can easily get the index of instance in WPF hit testing.
               wpfGeometryModel3D.SetValue(InstanceIndexProperty, i);


           return model3DGroup;

       private GeometryModel3D GenerateWpfGeometryModel3D(ref InstanceData instanceData)
           var material = GenerateWpfMaterial(instanceData.DiffuseColor);

           var geometryModel3D = new GeometryModel3D(MeshGeometry3D, material);
           geometryModel3D.Transform = new MatrixTransform3D(instanceData.World.ToWpfMatrix3D());

           return geometryModel3D;

       private Material GenerateWpfMaterial(Color4 color)
           return new DiffuseMaterial(new SolidColorBrush(color.ToWpfColor()));

After that you will be able to export that with AssimpWpfExporter.

Note that this will work, but it will not be very efficient. The problem is that currently, the AssimpWpfExporter creates a new Mesh from each GeometryModel3D - even if all GeometryModel3D objects are using the same instance of MeshGeometry3D new Mesgeh will be exported for each of them.

I am going to update the Ab3d.PowerToys.Assimp library to check if the same MeshGeometry3D instance we already used and in this case export that only once.

Then I will publish the updated Ab3d.PowerToys.Assimp library to GitHub so you will be able to get it. This way you will be also able to change the exporter if needed - maybe even providing a way to export ObjectNode objects without converting them to WPF objects.
Thanks a lot for the sample code, we will utilize this to be able to convert instanced meshes into individual meshes for export.