C# 将GeometryModel3D添加到Model3DGroup

C# 将GeometryModel3D添加到Model3DGroup,c#,wpf,3d,C#,Wpf,3d,我试图创建一个wpf应用程序,显示一个动画的三维模型。我有在BuildWave中创建模型的工作代码(我知道这和我以前使用过的一样有效)。但是,当我将代码移动到wpf窗口类中的后台工作程序时,我得到一个错误“调用线程无法访问此对象,因为另一个线程拥有它。” 我已经搜索了这个问题的解决方案,并找到了一篇文章,其中包含了一个带有相同错误()的问题,建议使用Dispatcher.Invoke()。然而,当我尝试这样做时: private void worker_Completed(object

我试图创建一个wpf应用程序,显示一个动画的三维模型。我有在BuildWave中创建模型的工作代码(我知道这和我以前使用过的一样有效)。但是,当我将代码移动到wpf窗口类中的后台工作程序时,我得到一个错误“调用线程无法访问此对象,因为另一个线程拥有它。”

我已经搜索了这个问题的解决方案,并找到了一篇文章,其中包含了一个带有相同错误()的问题,建议使用Dispatcher.Invoke()。然而,当我尝试这样做时:

    private void worker_Completed(object sender, RunWorkerCompletedEventArgs e)
    {
        GeometryModel3D model = (GeometryModel3D)e.Result;
        mGeometry = model.Clone();

        group.Dispatcher.Invoke(() =>
        {
            if (group.Children.Contains(mGeometry))
            {
                group.Children.Remove(mGeometry);
            }
            group.Children.Add(mGeometry);    //error is now thrown on this line
        });

        System.Diagnostics.Debug.WriteLine("Added geometry to group");
    }
这会引发错误“不能使用属于与其父Freezable不同线程的DependencyObject”。此外,还有一篇文章讨论了类似的问题(),建议冻结我在BuildWave中所做的模型:

        GeometryModel3D model = new GeometryModel3D(WaveMesh, new DiffuseMaterial(Brushes.YellowGreen));
        model.Transform = new Transform3DGroup();

        model.Freeze();
        return model;
我该怎么做才能解决这个问题


提前感谢。

由于它工作正常,请在bgworker中准备几何模型的所有数据(点列表、三角形顶点列表),不要使用gui对象,如
Point3DCollection
Int32Collection
或几何体。然后,当您准备好使用它时,在lambda方法中创建所有几何体等(您可以很高兴地将此创建提取到一个方法中以获得更高的可读性,并在lambda中调用它),您可以调用调度程序。这应该可以工作。

调用UI线程,如下所示:

public static Model3DCollection GetModel3DCollectionByTemplates(List<GeometryTemplate> geometryTemplates) {
        var modelCollection = new Model3DCollection();
        foreach (var geometryTemplate in geometryTemplates) {
            var positions = geometryTemplate.Positions;
            var indicies = geometryTemplate.Indicies;
            var normals = geometryTemplate.Normals;
            var meshGeometry3D = new MeshGeometry3D {
                Positions = new Point3DCollection(positions),
                TriangleIndices = new Int32Collection(indicies),
                Normals = new Vector3DCollection(normals)
            };
            var geometry = new GeometryModel3D(meshGeometry3D,
                new DiffuseMaterial(new SolidColorBrush(Colors.Aquamarine)));
            modelCollection.Add(geometry);
        }
        // =======================
        return modelCollection;
    }

其中_model3DGroupContainer是Model3DGroup

谢谢。我对代码的顺序以及在哪些线程中可以执行哪些操作感到困惑。。现在分类!
public static Model3DCollection GetModel3DCollectionByTemplates(List<GeometryTemplate> geometryTemplates) {
        var modelCollection = new Model3DCollection();
        foreach (var geometryTemplate in geometryTemplates) {
            var positions = geometryTemplate.Positions;
            var indicies = geometryTemplate.Indicies;
            var normals = geometryTemplate.Normals;
            var meshGeometry3D = new MeshGeometry3D {
                Positions = new Point3DCollection(positions),
                TriangleIndices = new Int32Collection(indicies),
                Normals = new Vector3DCollection(normals)
            };
            var geometry = new GeometryModel3D(meshGeometry3D,
                new DiffuseMaterial(new SolidColorBrush(Colors.Aquamarine)));
            modelCollection.Add(geometry);
        }
        // =======================
        return modelCollection;
    }
public class GeometryTemplate {
    public List<Point3D> Positions { get; private set; }
    public List<Int32> Indicies { get; private set; }
    public List<Vector3D> Normals { get; private set; }

    public GeometryTemplate(MeshGeometry3D meshGeometry3D) {
        SetPositions(meshGeometry3D.Positions);
        SetIndicies(meshGeometry3D.TriangleIndices);
        SetNormals(meshGeometry3D.Normals);
    }

    private void SetNormals(Vector3DCollection normals) {
        Normals = new List<Vector3D>(normals);
    }

    private void SetIndicies(Int32Collection triangleIndices) {
        Indicies = new List<Int32>(triangleIndices);
    }

    private void SetPositions(Point3DCollection positions) {
        Positions = new List<Point3D>(positions);
    }
}
_model3DGroupContainer.Children = model3DCollection;