The language : c# (wpf)
The situation : I have to load a 3D mesh from a file after which I populate a Viewport3D.
What do I want to do : I want to load the 3D mesh in a BackgroundWorker, so the application does not need to stall while loading the 3D mesh; this takes a few seconds.
The problem : The problem is NOT how to use BackgroundWorker. That's well documented. The problem arises when I want to populate the Viewport3D's Model3DGroup (3D object group).
When loading the 3D mesh from the file, in the background worker, I populate a custom mesh class with all the points and triangle indices of each object in the mesh. I store these in Point3DCollections and Int32Collections respectively.
public class LFSMeshObject
{
public Point3D Center;
public int Radius;
public int NumPoints;
public int NumTris;
public Color ObjectColor { get; private set; }
public Point3DCollection Points { get; private set; }
public Int32Collection Tris { get; private set; }
When this populated object is passed back to the GUI thread, I can read all values and properties stored in the object just fine. I can also read the Point3Dcollections and Int32Collections which I copy into MeshGeometry3D's which go into the Model3DGroup, but then get a thread owner exception, because the properties of the background populated object belong to the background thread.
DiffuseMaterial mDMat;
MeshGeometry3D mGeom;
Debug.WriteLine("num objects in mesh : {0}", _trackMesh.NumObjects);
for (int a = 0; a < _trackMesh.NumObjects; a++)
{
mGeom = new MeshGeometry3D();
mGeom.Positions = _trackMesh.TrackMeshObjects[a].Points;
mGeom.TriangleIndices = _trackMesh.TrackMeshObjects[a].Tris;
mDMat = new DiffuseMaterial();
mDMat.Brush = new SolidColorBrush(_trackMesh.TrackMeshObjects[a].ObjectColor);
// thread owner exception
_mgTrack.Children.Add(new GeometryModel3D(mGeom, mDMat));
}
Is the problem that I'm reading objects (Point3DCollection / Int32Collection) instead of plain values which would be copied, from the background-populated object?
Is it so that when you share data between threads, you have to create copies of all the data you want to use (in other object ie. MeshGeometry / Modelgroup) in the other thread? Can we not populate an object in the background and then 'simply use it' in another thread, after population is complete?